android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database still unable to fix issue

3.5k Views Asked by At

This question has already been asked by the people but going through the steps from many of them I am still unable to fix the problem at my end, please help. i also added the permission in manifest file

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

here is the logcat error.

07-17 15:23:58.253 14526-14526/com.techmobile2.yogahome E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.techmobile2.yogahome, PID: 14526
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.techmobile2.yogahome/com.techmobile2.yogahome.SettingPage}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2480)
    at android.app.ActivityThread.access$800(ActivityThread.java:151)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:155)
    at android.app.ActivityThread.main(ActivityThread.java:5725)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1030)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:825)
 Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:235)
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:219)
    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:468)
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:190)
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:182)
    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:874)
    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:854)
    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:752)
    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:727)
    at com.readystatesoftware.sqliteasset.SQLiteAssetHelper.getReadableDatabase(SQLiteAssetHelper.java:264)
    at com.techmobile2.yogahome.Database.YogaDB.getSettingMode**(YogaDB.java:21)**
    at com.techmobile2.yogahome.SettingPage.onCreate**(SettingPage.java:41)**
    at android.app.Activity.performCreate(Activity.java:6018)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2480) 
    at android.app.ActivityThread.access$800(ActivityThread.java:151) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:155) 
    at android.app.ActivityThread.main(ActivityThread.java:5725) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1030) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:825) 

here is the the yogaDB.java file i will mention the line number also

public class YogaDB extends SQLiteAssetHelper {

private static final String DB_NAME = "yoga.db";
private static final int DB_VER=1;

public YogaDB(Context context) {
    super(context, DB_NAME, null, DB_VER);
}

public int getSettingMode()
{
    **SQLiteDatabase db = getReadableDatabase();** //THIS is line 21
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    String[] sqlSelect = {"Mode"};
    String sqlTable = "Setting";

    qb.setTables(sqlTable);
    Cursor c = qb.query(db,sqlSelect,null,null,null,null,null);
    c.moveToFirst();
    return c.getInt(c.getColumnIndex("Mode"));
}

public void saveSettingMode(int value)
{
    SQLiteDatabase db = getReadableDatabase();
    String query = "UPDATE Setting SET Mode = "+value;
    db.execSQL(query);
}

and here is the SettingPage.java and i will also mention line number

public class SettingPage extends AppCompatActivity {

Button btnSave;
RadioButton rdiEasy,rdiMedium,rdiHard;
RadioGroup rdiGroup;
YogaDB yogaDB;
ToggleButton switchAlarm;
TimePicker timePicker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_setting_page);

    //Init view
    btnSave = (Button)findViewById(R.id.btnSave);
    rdiGroup = (RadioGroup)findViewById(R.id.rdiGroup);
    rdiEasy = (RadioButton)findViewById(R.id.rdiEasy);
    rdiMedium = (RadioButton)findViewById(R.id.rdiMedium);
    rdiHard = (RadioButton)findViewById(R.id.rdiHard);

    switchAlarm = (ToggleButton)findViewById(R.id.switchAlarm);

    timePicker = (TimePicker)findViewById(R.id.timePicker);

    yogaDB = new YogaDB(this);

    int mode = yogaDB.getSettingMode(); this is line 41
    setRadioButton(mode);

    //Event
    btnSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            saveWorkoutMode();
        }
    });

}

private void saveWorkoutMode() {
    int selectedID = rdiGroup.getCheckedRadioButtonId();
    if(selectedID == rdiEasy.getId())
        yogaDB.saveSettingMode(0);
    else if(selectedID == rdiMedium.getId())
        yogaDB.saveSettingMode(1);
    else if(selectedID == rdiHard.getId())
        yogaDB.saveSettingMode(2);
}

private void setRadioButton(int mode) {
    if(mode == 0)
        rdiGroup.check(R.id.rdiEasy);
    else if(mode == 1)
        rdiGroup.check(R.id.rdiMedium);
    else if(mode == 2)
        rdiGroup.check(R.id.rdiHard);
}

and my sql database file name is yoga.db please help me to solve my problem

1

There are 1 best solutions below

1
Umer Khan On BEST ANSWER

Issue: Most of the times SQLiteCantOpenDatabaseException occurs when you are access your sqlite database from multiple threads. Let say you have opened the database in one thread and trying to access the database in another will cause SQLiteCantOpenDatabaseException exception.

Solution: Make a singleton object of your SQLiteOpenHelper class and always use the same instance for multiple threads.

Sample:

DBHelper class:

public class DBHelper extends SQLiteOpenHelper {
  private DBHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }

  public synchronized static DBHelper getInstance(Context context) {
    if (dbHelper == null) {
        dbHelper = new DBHelper(context);
    }

    return dbHelper;
  }

  @Override
  public void onCreate(SQLiteDatabase sqLiteDatabase) {
    //...
  }

  @Override
  public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    //...
    onCreate(sqLiteDatabase);
  }
}

Usage:

private static SQLiteDatabase database;


DBHelper dbHelper = DBHelper.getInstance(context);
if (database == null) {
  database = dbHelper.getWritableDatabase();
}

Note: Never close the SqliteDatabase instance yourself android system does it for you.