1

I simply try to open a database in READWRITE Mode. I get the following error: "not an error (code 0): Could not open the database in read/write mode." When opening the DB the same way but READONLY is works. On my 3 devices this is not a problem opening in READWRITE, but 2 users reported that following error.

the db exists on the users filesystem . I check this with file.exists() -> ok. the db-file is readwrite able on the users device. I check this with file.canWrite() -> ok.

the dbfile is stored under :

StoragePath : /mnt/extSdCard/mypath/mydb.db

New Info on 09.03.2014 : It seems to be only a problem in KitKat 4.4.2. Since Users have updated to 4.4.2 they get this problem.

My Code:

public void onCreate(Bundle savedInstanceState) {


connectWriter(); // throws exception below.

public void connectWriter() {
        chronica_connection_readwrite = SQLiteDatabase.openDatabase("MyPath", null, SQLiteDatabase.OPEN_READWRITE);
        //chronica_connection_read.enableWriteAheadLogging();
    }

Exception Report:

java.lang.RuntimeException: Unable to start activity ComponentInfo{...}: android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2340)
at android.app.ActivityThread.access$800(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:342)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:232)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:515)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:207)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:891)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:859)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
at myclass.connectWriter(ChronicBrowser.java:14286)
at myclass.LoadModule(ChronicBrowser.java:10792)
at myclass.onCreate(ChronicBrowser.java:761)
at android.app.Activity.performCreate(Activity.java:5389)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)


************ DEVICE INFORMATION ***********
Brand: samsung
Device: hlte
Model: SM-N9005
Id: KOT49H
Product: hltexx

************ FIRMWARE ************
SDK: 19
Release: 4.4.2
Incremental: N9005XXUENB7 
mcfly soft
  • 11,289
  • 26
  • 98
  • 202
  • Why don't you use a `SQLiteOpenHelper`? You wouldn't have to deal directly with the database for opening in different modes. – Squonk Mar 08 '14 at 10:13
  • I really would like to use my connection as mentoined. My database is not created by the app and I have no versioning. My db will be downloaded by my app.. I guess this should be possible to open a readwrite connection on every device. Any hints ? – mcfly soft Mar 08 '14 at 13:12
  • Are all the devices running the same android version? I'd suggest suign SQLiteOpenHelper, you can always maintain the version number in your app. I don't think that's a good excuse not to use SQLiteOpenHelper. I also download the db file into my app from an external source and yet I am using SQLiteOpenHelper and maintaining the version inside my app. – Saeid Farivar Mar 09 '14 at 00:57
  • I will try it, but according to http://stackoverflow.com/questions/16373722/sqlitedatabase-opendatabase-vs-getwritabledatabase there is no need to use SQLiteOpenHelper to open a database in readwrite mode. I aslo like to use "enableWriteAheadLogging" logging, which I do not know how this is supported by SQLiteOpenHelper. – mcfly soft Mar 09 '14 at 09:27
  • See also http://stackoverflow.com/questions/6193279/sqlitedatabase-opendatabase-vs-sqliteopenhelper-getreadabledatabase . There seems no difference between SQLiteDatabase.openDatabase vs SQLiteOpenHelper.getReadableDatabase regarding opening a db. – mcfly soft Mar 09 '14 at 09:46
  • News on this : It seems only to be a problem with KitKat Android 4.4.2. Users reported, that the error occurs after updating to KitKat. A bug probably :-( – mcfly soft Mar 09 '14 at 17:48
  • Confirm: I do have the same problem. While app was in 4.2 everything was fine, but now when I have upgraded to KitKat I see problem. Issue roots are the same - I have db on SD card. Device is SGS-4. Please help! – Barmaley Mar 13 '14 at 17:45
  • As another way you can try to store your data in alternate db like JDBM or simply excel file if you don't need protect your storage – Gorets Mar 14 '14 at 11:16
  • The Problem is, that also handling with files (write) is a problem in KITKAT. I just got a errorreport regarding unzipping a file on a filesystem, which works great since 2 years. :-( KitKat has a problem with write access. – mcfly soft Mar 14 '14 at 12:34

2 Answers2

2

Looks like that this is not bug, but "feature".

Google's KitKat Blocks Some Access to Micro SD Cards

It's really sad, but looks like true

Barmaley
  • 16,638
  • 18
  • 73
  • 146
  • I was able to fix the problem by moving the database to internal storage on a Galaxy S4 after it upgraded to 4.4.2. I agree it's sad, as it now uses up internal memory while there is plenty on the SD card. Hopefully there is another way around it. – Kenneth Evans May 17 '14 at 15:46
1

I'll preface this by saying you should really be storing SQLite databases on internal storage, where you have the benefit of ext4 journaling to help with data recovery. There is also much better security on internal storage, since you don't have to worry about malicious apps adding triggers, etc that end up running in your process.

That all being said, starting in KitKat you can write to secondary storage devices through the new public APIs Context.getExternalFilesDirs() or Context.getExternalCacheDirs(). These methods are also available on ContextCompat in the support-v4 library.

Also note that if you're only interested in using the directories returned by Context, you no longer need the READ_ or WRITE_EXTERNAL_STORAGE permissions. Going forward, you'll always have read/write access to these directories with no additional permissions required.

Apps can also continue working on older devices by end-of-lifing their permission request like this:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
Jeff Sharkey
  • 2,473
  • 1
  • 17
  • 10
  • So, using these APIs `Context.getExternalFilesDirs()`, help us to store SQLite db in the secondary storage ? I think these are the APIs for storing some files related to our app but not sqlite db. Please correct me if I am wrong. – Chaitanya Aug 02 '16 at 09:30