android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
Asked Answered
T

22

75

I have read various on site about this issue but I am not able to figure this out. I am using pre-build database for this app. I am using jellybean for this app.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.quotes"
        android:versionCode="1"
        android:versionName="1.0" >

        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />

        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.quotes.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

    </manifest>

Logcat Output

according to logcat it's caused by SQLiteCantOpenDatabaseException

06-10 23:07:01.831: E/Trace(4419): error opening trace file: No such file or directory (2)
06-10 23:07:03.611: E/SQLiteLog(4419): (14) cannot open file at line 30176 of [00bb9c9ce4]
06-10 23:07:03.621: E/SQLiteLog(4419): (14) os_unix.c:30176: (2) open(/data/data/com.example.quotes/databasesQuotesdb) - 
06-10 23:07:03.641: E/SQLiteDatabase(4419): Failed to open database '/data/data/com.example.quotes/databasesQuotesdb'.
06-10 23:07:03.641: E/SQLiteDatabase(4419): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at com.example.quotes.DataBaseHelper.checkDataBase(DataBaseHelper.java:94)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at com.example.quotes.DataBaseHelper.createDataBase(DataBaseHelper.java:58)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at com.example.quotes.MainActivity.onCreate(MainActivity.java:34)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.Activity.performCreate(Activity.java:5104)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.os.Looper.loop(Looper.java:137)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at android.app.ActivityThread.main(ActivityThread.java:5041)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at java.lang.reflect.Method.invokeNative(Native Method)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at java.lang.reflect.Method.invoke(Method.java:511)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-10 23:07:03.641: E/SQLiteDatabase(4419):     at dalvik.system.NativeStart.main(Native Method)
06-10 23:07:03.731: E/SQLiteLog(4419): (14) cannot open file at line 30176 of [00bb9c9ce4]
06-10 23:07:03.731: E/SQLiteLog(4419): (14) os_unix.c:30176: (2) open(/data/data/com.example.quotes/databasesQuotesdb) - 
06-10 23:07:03.781: E/SQLiteDatabase(4419): Failed to open database '/data/data/com.example.quotes/databasesQuotesdb'.
06-10 23:07:03.781: E/SQLiteDatabase(4419): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at com.example.quotes.DataBaseHelper.openDataBase(DataBaseHelper.java:145)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at com.example.quotes.MainActivity.onCreate(MainActivity.java:44)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.Activity.performCreate(Activity.java:5104)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.os.Looper.loop(Looper.java:137)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at android.app.ActivityThread.main(ActivityThread.java:5041)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at java.lang.reflect.Method.invokeNative(Native Method)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at java.lang.reflect.Method.invoke(Method.java:511)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-10 23:07:03.781: E/SQLiteDatabase(4419):     at dalvik.system.NativeStart.main(Native Method)
06-10 23:07:03.791: D/AndroidRuntime(4419): Shutting down VM
06-10 23:07:03.791: W/dalvikvm(4419): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
06-10 23:07:03.831: E/AndroidRuntime(4419): FATAL EXCEPTION: main
06-10 23:07:03.831: E/AndroidRuntime(4419): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quotes/com.example.quotes.MainActivity}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.os.Looper.loop(Looper.java:137)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread.main(ActivityThread.java:5041)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at java.lang.reflect.Method.invokeNative(Native Method)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at java.lang.reflect.Method.invoke(Method.java:511)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at dalvik.system.NativeStart.main(Native Method)
06-10 23:07:03.831: E/AndroidRuntime(4419): Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at com.example.quotes.DataBaseHelper.openDataBase(DataBaseHelper.java:145)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at com.example.quotes.MainActivity.onCreate(MainActivity.java:44)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.Activity.performCreate(Activity.java:5104)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
06-10 23:07:03.831: E/AndroidRuntime(4419):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
06-10 23:07:03.831: E/AndroidRuntime(4419):     ... 11 more
06-10 23:07:04.083: D/dalvikvm(4419): GC_CONCURRENT freed 203K, 11% free 2676K/3000K, paused 25ms+18ms, total 306ms
06-10 23:07:07.811: I/Process(4419): Sending signal. PID: 4419 SIG: 9

DataBaseHelper.java

public class DataBaseHelper extends SQLiteOpenHelper{

    //The Android's default system path of your application database.
    private static String DB_PATH = "/data/data/com.example.quotes/databases";

    private static String DB_NAME = "Quotesdb";

    // Table Names of Data Base.
    static final String TABLE_Name = "Quotes";

    // Contacts Table Columns names
    //private static final String _Id = "_Id";
    //private static final String quotes = "quotes";
    //private static final String author = "author";

    private SQLiteDatabase myDataBase; 

    private final Context myContext;

    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
     * @param context
     */
    public DataBaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     * */
    public void createDataBase() throws IOException{

        boolean dbExist = checkDataBase();
        SQLiteDatabase db_Read = null;

        if(dbExist){
            //do nothing - database already exist
        }else{
            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.
            db_Read = this.getReadableDatabase(); 
            db_Read.close();

            try {
                copyDataBase();
            } catch (IOException e) {
                //throw new Error("Error copying database");
                e.toString();
            }
        }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        }catch(SQLiteException e){
            //database does't exist yet.
        }

        if(checkDB != null){
            checkDB.close();
        }

        return checkDB != null ? true : false;
    }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     * */
    private void copyDataBase() throws IOException{

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
        }

        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public void openDataBase() throws SQLException{
        //Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }

    @Override
    public synchronized void close() {
        if(myDataBase != null)
            myDataBase.close();

        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }

    /*// Getting single contact
    public List<Quotes> getQuote(int id) {
        ArrayList<Quotes>();
        getReadableDatabase();

        Cursor cursor = db.query(TABLE_Name, new String[] { _Id,
                qotes,author }, _Id + "=?", new String[] { String.valueOf(id) },
                null, null, null, null);

        //String query = "SELECT _Id, qotes, author From "+TABLE_Name;
        //String query = "SELECT * From Quotes";

        //Cursor cursor = db.rawQuery(query, null);

        if (cursor != null)
            cursor.moveToFirst();
        Quotes quotes = new Quotes(Integer.parseInt(cursor.getString(0)),
        cursor.getString(1),cursor.getString(2));
        QuoteList.add(quotes);
        return QuoteList;
    }
    */
}
Tierza answered 10/6, 2013 at 23:40 Comment(8)
Please provide more information. In particular, what do you do that causes this error?Hermanhermann
I am running this on emulator and it crashes. Unfortunately app has stopped.Tierza
I am not using SQLiteAssetHelperTierza
I'm getting the same problem when running an ActivityInstrumentationTestCase2Continental
What if you created the a database in the onCreate?Quarterhour
Also can you give some information on how you built the database?? And do you have the necessary permission in the manifest for writing to filesystem.Hinckley
@Tierza : Hi How did your problem resolved ??? I am facing similar problem with similar code .Patron
Just a note, I solve this similar error for notification by uninstall and re-install app.Shaneka
P
41

Add this permission to your project's AndroidManifest.xml file, in the manifest tag (which should be the top level tag).

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Pricking answered 5/11, 2013 at 6:32 Comment(5)
Ooooh!! Totally forgot this!! Thank you very muchVirile
Note: With android marshmallow, you have to implement a permission request first, because reading and writing the external storage is a dangerous permission. More information: developer.android.com/training/permissions/requesting.htmlMicamicaela
The path is "/data/data/com.example.quotes/databases" Internal storage, why we need external_storage permission?Datum
Why it is so highly upvoted? @Datum is right, we don't need permission. And Felix Edelmann said that we need request permission starting with Android M. In this scenario every app would ask read/write storage permission from the first launchMangan
You must ask for the permission for the first time. Besides this, the above permission must be in the manifest file.Pricking
T
27

Replace the checkDataBase() code with the code below:

File dbFile = myContext.getDatabasePath(DB_NAME);
return dbFile.exists();
Taipan answered 24/7, 2013 at 23:52 Comment(0)
H
18

You may face this issue if you are running your app on Android's Marshmallow or later version (API level 23 or greater), because of the new Real-time Permissions model introduced in this.

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app.

For getting permissions at runtime, you will have to request the user. You can do that in following way.

First request for permissions.

String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
        requestPermissions(permissions, WRITE_REQUEST_CODE);

And then you can check the results in

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
       case WRITE_REQUEST_CODE:
         if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
           //Permission granted.
           //Continue with writing files...
         }
       else{
           //Permission denied.
         }
        break;
    }
}

Here is good learning source requesting-runtime-permissions-in-android-marshmallow/

Harbard answered 18/1, 2016 at 14:22 Comment(2)
In what part of code should I ask to requestPermissions?Aldarcy
As per developer.android.com/reference/android/…, "starting in API level 19, this permission is not required to read/write files in your application-specific directories". So is the db not created in application specific area?Refugia
H
14

This can be caused by bad permissions or SELinux. Ensure the permissions, and owner/group are correctly set. Then run this:

restorecon /data/data/your.app.folder/databases/your.db

restorecon restores file default SELinux security context

Heron answered 16/4, 2016 at 6:36 Comment(3)
Android 7.0 required the -F flag for force until it worked. restorecon -FLibelant
@Benoit Duffez could you please share more on SELInux part on this issue? I am working on system apps and getting same error in one cycle.Cornet
@Shijil: no, sorry, I can't. It was from a phone I had 7 years ago and I don't know what would be applicable today.Heron
K
5

I think it's because your DB_Path finishes without a "/". When you concatenate the path with the database, the variable myPath has the following string: "/data/data/com.example.quotes/databasesQuotesdb".

I propose these changes:

private static String DB_PATH = "/data/data/com.example.quotes/databases/";
private static String DB_NAME = "Quotesdb.db";

And another thing, you should open the database in the Main activity, and implement the onPause() and onResume() methods with database.close() and database.open() respectively. This is my example for the Main Activity (used with Cordova, web design and all the stuff =P):

package home.shell.accessApp;

import android.os.Bundle;
import android.util.Log;

import org.apache.cordova.*;

public class AccessApp extends CordovaActivity {    

    private SellitDAO db; //This is the class name for my SQLiteOpenHelper

    @Override
    public void onCreate(Bundle savedInstanceState) {
        db = new SellitDAO(this);
        db.open();

        super.onCreate(savedInstanceState);
        super.init();
        // Set by <content src="index.html" /> in config.xml
        super.loadUrl(Config.getStartUrl());
        //super.loadUrl("file:///android_asset/www/index.html")
    }

    @Override
    public void onPause() {
        super.onPause();
        db.close();
    }

    @Override
    public void onResume() {
        super.onResume();
        db.open();
    }
}

Good Luck!!!

Kapoor answered 11/10, 2013 at 23:5 Comment(0)
A
4

The DB_PATH was pointing to different database. Change it in database helper class and my code working.

private static String DB_PATH = "/data/data/com.example.abc";
Ariellearies answered 6/8, 2013 at 20:20 Comment(0)
S
4

@nmr also check the ownership and groups on the sqlite file itself... I'd copied my database in from /sdcard as root so had to change the permissions..

-rw-rw---- root     root       180224 2014-05-05 11:06 test.sqlite

should be..

-rw-rw---- u0_a80   u0_a80     180224 2014-05-05 11:06 test.sqlite

Used the following commands to set the correct ownership and group. The u0_a80 I got from ls -al on other files in the directory

chown u0_a80 test.sqlite
chgrp u0_a80 test.sqlite
Sting answered 5/5, 2014 at 10:53 Comment(0)
H
3

I don't think this is your problem, but it still looks pretty bad to me. You have a duplicate layer of com.examples.quote in your project. Your Activity section in your AndroidManifest.xml should look more like this:

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

You may even have your classes under src/com.example.quotes/com.example.quotes instead of just in com.example.quotes.

I'm not sure if this is causing your problem. But it looks a bit messed up. All your other stuff looks pretty standard to me.

Havenot answered 11/6, 2013 at 5:47 Comment(0)
S
3

I lately came up with this error. But it was even more odd. I was working on Android N and everything was going smoothly OK, until I test it on JellyBeans and Lollipop. In which I kept on getting the same DB error.

android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database 06-10 23:07:03.641: E/SQLiteDatabase(4419):

I had the right permissions in my manifest, including:

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

The problem was this line in my DataBaseHelper.java:

private static String DB_PATH = "/data/data/com.example.quotes/databases";

which needed to be loaded from the context this way:

String DB_PATH = getContext().getApplicationInfo().dataDir+"/databases/";

Now is working properly form SDK 17.

Slaughter answered 12/1, 2018 at 4:17 Comment(3)
I wish, I would come through this post earlier, it would save my 2 days.Warbler
Replacing getContext().getApplicationInfo().dataDir+"/databases/"; with new File(getContext().getApplicationInfo().dataDir, "databases").getAbsolutePath(); will handle adding the necessary path separator.Neocolonialism
Only this one worked for me.Newcomen
P
2

My gremlin for this problem was bad directory permissions:

Good permissions:

drwxr-x--x u0_a20   u0_a20            2013-11-13 20:45 com.google.earth
drwxr-x--x u0_a63   u0_a63            2013-11-13 20:46 com.nuance.xt9.input
drwxr-x--x u0_a53   u0_a53            2013-11-13 20:45 com.tf.thinkdroid.sg
drwxr-x--x u0_a68   u0_a68            2013-12-24 15:03 eu.chainfire.supersu
drwxr-x--x u0_a59   u0_a59            2013-11-13 20:45 jp.co.omronsoft.iwnnime.ml
drwxr-x--x u0_a60   u0_a60            2013-11-13 20:45 jp.co.omronsoft.iwnnime.ml.kbd.white
drwxr-x--x u0_a69   u0_a69            2013-12-24 15:03 org.mozilla.firefox

Bad permissions:

root@grouper:/data/data # ls -lad com.mypackage                  
drw-rw-r-- u0_a70   u0_a70            2014-01-11 14:18 com.mypackage

How did they get that way? I set them that way, while fiddling around trying to get adb pull to work. Clearly I did it wrong.

Hey Google, it would be awful nice if a permission error produced a meaningful error message, or failing that if you didnt have to hand tweak permissions to use the tools.

Premeditate answered 11/1, 2014 at 22:39 Comment(0)
P
2

Another thing to note is Environment.getExternalStorageDirectory() has been deprecated in API 29, so change this if you're using this to get the database path:

https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory()

This method was deprecated in API level 29.

To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

Polygamy answered 16/2, 2020 at 15:39 Comment(0)
A
1

In runtime problems like these firstly open logcat if you are using android studio, try to analyse trace tree, go to the beginning from where exception started to rise, since that is usually the source of the problem. Now check for two things:

  1. Check in device file explorer(on the bottom right) there exist a database created by you. mostly you find it in DATA -> DATA -> com.example.hpc.demo(your pakage name) -> DATABASE -> demo.db

  2. Check that in your helper class you have added required '/' for example like below
    DB_location = "/data/data/" + mcontext.getPackageName() + "/databases/";

Anthropocentric answered 16/9, 2018 at 11:38 Comment(0)
L
0

Add before OpenDatabase this lines:

File outFile = new File(Environment.getDataDirectory(), outFileName);
outFile.setWritable(true);
SQLiteDatabase.openDatabase(outFile.getAbsolutePath(), null, SQLiteDatabase.OPEN_READWRITE);
Limoges answered 3/12, 2015 at 10:20 Comment(0)
H
0

As mentioned by @CommonsWare, you will want to try android sqlite asset helper. It made opening a pre-existing db a piece of cake for me.

I literally had it working in about a half hour after spending 3 hours trying to do it all manually. Funny thing is, I thought I was doing the same thing the library did for me, but something was missing!

Halfcocked answered 6/1, 2016 at 18:8 Comment(0)
C
0

Clearing application data helped me in this. It may help you..

Cahill answered 17/2, 2016 at 15:37 Comment(0)
A
0

Android's default system path of your application database is /data/data/YOUR_PACKAGE/databases/YOUR_DB_NAME

Your logcat clearly says Failed to open database '/data/data/com.example.quotes/databasesQuotesdb'

Which means there is no file present on the given path or You have given the wrong path for the data file. As I can see there should be "/" after databases folder.

Your DB_PATH variable should end with a "/".

private static String DB_PATH = "/data/data/com.example.quotes/databases/";

Your correct path will be now "/data/data/com.example.quotes/databases/Quotesdb"

Alexaalexander answered 5/9, 2018 at 20:6 Comment(0)
O
0

you must use this way for path:

DB_PATH=  context.getDatabasePath(DB_NAME).getPath();
Offen answered 13/12, 2018 at 20:33 Comment(0)
A
0

android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

If you are getting this after replacing your database files using the Device File Explorer, sometimes this happens due to permissions and SELinux security contexts. The Device File Explorer (as of AS3.6.3) will upload them with root permissions/rwxrwxrwx set for all (777). Look around in your app folders for the user id used for your app. Execute the following commands in terminal:

   adb devices
   emulator-5554
   adb root
   adb -s emulator-5554 shell
   cd /data/data/com.yourorg.yourapp
   ls -l

You'll get a listing like:

drwxrwx--x 2 u0_a85 u0_a85 4096 2020-04-23 16:09 cache
drwxrwx--x 2 u0_a85 u0_a85 4096 2020-04-23 16:09 code_cache
drwxrwx--x 2 u0_a85 u0_a85 4096 2020-04-23 16:09 databases
drwxrwx--x 2 u0_a85 u0_a85 4096 2020-04-23 16:09 shared_prefs

u0_a85 (or whatever it might be) will be the app owner and group id. Delete your databases on the device, drop in your replacement database files using Device File Explorer, and in terminal, execute the following (keeping in mind the owner id):

cd databases
chown u0_a85 *.db; chgrp u0_a85 *.db; chmod 600 *.db; restorecon *.db

This changes the database files to their appropriate owner/group id, RW permissions, and resets the SELinux security contexts for those files. Although I have had success replacing database files NOT having to do this, this problem seems to happen randomly enough that doing this works.

Armorer answered 23/4, 2020 at 21:50 Comment(0)
C
0

I had this issue as a user not as a developer. and and the reason was different in my case.

https://del.dog/ufinunacul.txt
It turned out that the data folder add a broken link pointing to my memory card second partition where I store app data on removing the broken link everything was fine

Chicoine answered 22/3, 2021 at 7:24 Comment(0)
M
0

This is caused because you do not have External Storage Write Permission at the time of initialization of SQLitedatabase object. i.e

db2=SQLiteDatabase.openOrCreateDatabase(DBPATH, null);

It may be because you are requesting permission but you haven't yet now allowed permission but the database instance is initialized. Keep In mind that external storage permissions are necessary to create a database file. Make all the write operations only after you allowed permission. You can do it in onRequestPermissionsResult.

Mccallum answered 25/3, 2021 at 6:22 Comment(0)
I
0
   <uses-permission
    android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
    tools:ignore="ProtectedPermissions" />
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />
<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

and add application tag

    android:requestLegacyExternalStorage="true"

Additionally, here's the code snippet to be added to your main activity:

    if (Build.VERSION.SDK_INT >= 30) {
    if (!Environment.isExternalStorageManager()) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("Please Allow File Access")
                .setPositiveButton("Go To Settings", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finishAffinity();
                    }
                });
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
    } else {
        // Proceed with your app logic
    }
} else {
    // Proceed with your app logic for lower SDK versions
}
Introductory answered 19/3 at 7:20 Comment(0)
M
-1

Please make sure you are not trying to open and close the database repeatedly either from main thread or background thread.

Make a singleton class in your application and try to create and open data from this class only.

Is guarantees you that database open call is made only when it does not exist.

In your entire application use the same approach of getting sqLiteDatabase object when it is required.

I used below code and my problem is solved now after 1.5 days.

...............................................................

In Your Activity class onCreate() method

public class MainActivity extends AppCompatActivity   {  
   private AssetsDatabaseHelper helper;    

@Override        
protected void onCreate(Bundle savedInstanceState) {        
helper = AssetsDatabaseHelper.getInstance(this);      
    sqLiteDatabase = helper.getDatabase();     
    }    
}    

public class AssetsDatabaseHelper {    
    Context context;    
    SQLiteDatabase sqLiteDatabase;    
    DatabaseHelper databaseHelper;    
    private static AssetsDatabaseHelper instance;    

    private  AssetsDatabaseHelper(Context context){    
        this.context = context;    

        databaseHelper = new DatabaseHelper(context);    
        if(databaseHelper.checkDatabase()){    
            try{    
                databaseHelper.openDatabase();    
            }catch(SQLException sqle){    
                Log.e("Exception in opening ", " :: database :: sqle.getCause() : "+sqle.getCause());    
            }    
        }else{    
            try{    
                databaseHelper.createDatabase();    
            }catch(IOException ioe){    
                Log.d("Exception in creating ", " :: database :: ioe.getCause() : "+ioe.getCause());    
            }
            try{    
                databaseHelper.openDatabase();    
            }catch(SQLException sqle){    
Log.e("Exception in opening ", " :: database :: "+sqle.getCause());    
            }    
        }
         sqLiteDatabase = databaseHelper.getSqLiteDatabase();    
    }    

    public static AssetsDatabaseHelper getInstance(Context context){    
        if(instance != null){    
            return instance;    
        }else {     
            instance = new AssetsDatabaseHelper(context);    
            return instance;     
        }    
    }  


    public SQLiteDatabase getDatabase(){    
        return sqLiteDatabase;        
    }      
}    
Mazuma answered 30/9, 2016 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.