Указанный каталог или файл базы данных не существует - PullRequest
0 голосов
/ 28 августа 2018

Я работаю над своими проектами Android в течение многих лет, и я всегда использую этот код для работы с базой данных, чтобы настроить базу данных sqlite, но в эти дни я установил Android Studio на новый ноутбук и начал запускать свои проекты, но я получаю это сообщение об ошибке один раз запущено приложение:

08-26 13:41:51.044 16032-16032/com.nileworx.flagsquiz E/SQLiteLog: (28) failed to open "/data/data/com.nileworx.flagsquiz/databases/FlagsQuiz" with flag (131072) and mode_t (0) due to error (2)
    (14) cannot open file at line 32561 of [a66a5b397b]
    (14) os_unix.c:32561: (2) open(/data/data/com.nileworx.flagsquiz/databases/FlagsQuiz) - 
08-26 13:41:51.054 16032-16032/com.nileworx.flagsquiz E/SQLiteDatabase: Failed to open database '/data/data/com.nileworx.flagsquiz/databases/FlagsQuiz'.
    android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 1294): Could not open database
    #################################################################
    Error Code : 1294 (SQLITE_CANTOPEN_ENOENT)
    Caused By : Specified directory or database file does not exist.
        (unknown error (code 1294): Could not open database)
    #################################################################
        at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
        at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:301)
        at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:220)
        at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:512)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
        at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:908)
        at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:878)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:674)
        at com.nileworx.flagsquiz.DataBaseHandler.checkDataBase(DataBaseHandler.java:86)
        at com.nileworx.flagsquiz.DataBaseHandler.createDataBase(DataBaseHandler.java:47)
        at com.nileworx.flagsquiz.DAO.<init>(DAO.java:52)
        at com.nileworx.flagsquiz.CustomDialog.<init>(CustomDialog.java:46)
        at com.nileworx.flagsquiz.MainActivity.onCreate(MainActivity.java:73)
        at android.app.Activity.performCreate(Activity.java:6609)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3113)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3275)
        at android.app.ActivityThread.access$1000(ActivityThread.java:218)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1744)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:145)
        at android.app.ActivityThread.main(ActivityThread.java:7007)
        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:1404)

Это мой DatabaseHandler.java:

package com.nileworx.flagsquiz;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBaseHandler extends SQLiteOpenHelper {

    // The Android's default system path of your application database.
    private static String DB_PATH;

    private static String DB_NAME = "FlagsQuiz";

    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 DataBaseHandler(Context context) {

        super(context, DB_NAME, null, 1);
        this.myContext = context;
        DB_PATH = context.getDatabasePath(DB_NAME).toString();
//      Log.e("path", DB_PATH);
    }

    // ==============================================================================

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

        boolean dbExist = checkDataBase();

        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.
            this.getReadableDatabase();

            try {

                copyDataBase();

            } catch (IOException e) {

                throw new Error("Error copying database");

            }
        }

    }

    // ==============================================================================

    /**
     * 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;
            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("database/" + DB_NAME);

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

        // 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;
        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) {

    }

    // ==============================================================================

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    // Add your public helper methods to access and get content from the
    // database.
    // You could return cursors by doing "return myDataBase.query(....)" so it'd
    // be easy
    // to you to create adapters for your views.

}

И это моя структура каталогов базы данных:
enter image description here

Файл манифеста:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.nileworx.flagsquiz"
    android:versionCode="7"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        tools:replace="android:label"
        android:largeHeap="true"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.gms.games.APP_ID"
            android:value="@string/app_id" />

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.nileworx.flagsquiz.UpdatesDialogActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Dialog" >
        </activity>
        <activity
            android:name="com.nileworx.flagsquiz.GameActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name="com.nileworx.flagsquiz.SettingsActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
        </activity>
        <activity
            android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />

        <service android:name="com.nileworx.flagsquiz.GetUpdatesService" >
        </service>
        <service android:name="com.nileworx.flagsquiz.CheckUpdatesService" >
        </service>
    </application>

</manifest>

DAO.java

public DAO(Context context) {
        dbHandler = new DataBaseHandler(context);
        try {

            dbHandler.createDataBase();

        } catch (IOException ioe) {

            throw new Error("Unable to create database");

        }
        try {

            dbHandler.openDataBase();

        } catch (SQLException sqle) {

            throw sqle;

        }
        // Log.e("path2",
        // context.getDatabasePath("FootballFlagQuiz").toString());
    }

Теперь, как я могу решить эту проблему? Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Ваш код в порядке.

Я скопировал весь код, который вы предоставили, и попытался воссоздать ошибки, которые у вас есть.

Сначала следует ожидать трассировки стека, которую вы показываете, поскольку это результат перехвата (перехваченного через catch), который неизбежен при использовании (в методе checkDB): -

checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

и база данных не существует. Трассировка стека не из ФАТАЛЬНОГО ИСКЛЮЧЕНИЯ. Однако сама трассировка стека выдается в методе openDatabase, поэтому не может быть легко подавлена.

Таким образом, любое ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ должно быть в другом месте. Вы должны проверить журнал дальше.

Запуск вашего кода без правильно названного файла (например, FlagsQuiz.txt в отличие от FlagsQuiz ) приводит к (примечание, что в ваш код добавлено ведение журнала)

т.е.. два файла, используемые для тестирования (расширение NOTADB не является базой данных sqlite, расширение txt является допустимой базой данных sqlite с добавленным расширением): -

enter image description here

Результат: -

08-29 01:01:19.323 2602-2602/? D/CHKDB: Issuing openDatabase for path :- /data/data/so52053932.so52053932/databases/FlagsQuiz
08-29 01:01:19.331 2602-2602/? E/SQLiteLog: (14) cannot open file at line 30174 of [00bb9c9ce4]
    (14) os_unix.c:30174: (2) open(/data/data/so52053932.so52053932/databases/FlagsQuiz) - 
08-29 01:01:19.331 2602-2602/? E/SQLiteDatabase: Failed to open database '/data/data/so52053932.so52053932/databases/FlagsQuiz'.
    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:209)
        at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
        at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
        at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
        at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
        at so52053932.so52053932.DataBaseHandler.checkDataBase(DataBaseHandler.java:89)
        at so52053932.so52053932.DataBaseHandler.createDataBase(DataBaseHandler.java:48)
        at so52053932.so52053932.DAO.<init>(DAO.java:17)
        at so52053932.so52053932.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
08-29 01:01:19.331 2602-2602/? D/CHECKDB: SQLiteException has bee caught.
08-29 01:01:19.339 2602-2602/? D/ONCREATE: New Database has been created so ONCREATE has been invoked.
08-29 01:01:19.339 2602-2602/? D/CPYDB: Database Copy Initiated. Trying to open InputStream i.e. asset database/FlagsQuiz
08-29 01:01:19.339 2602-2602/? W/System.err: java.io.FileNotFoundException: database/FlagsQuiz
        at android.content.res.AssetManager.openAsset(Native Method)
        at android.content.res.AssetManager.open(AssetManager.java:315)
        at android.content.res.AssetManager.open(AssetManager.java:289)
        at so52053932.so52053932.DataBaseHandler.copyDataBase(DataBaseHandler.java:119)
        at so52053932.so52053932.DataBaseHandler.createDataBase(DataBaseHandler.java:62)
        at so52053932.so52053932.DAO.<init>(DAO.java:17)
        at so52053932.so52053932.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
08-29 01:01:19.347 2602-2602/? W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
08-29 01:01:19.347 2602-2602/? D/AndroidRuntime: Shutting down VM
08-29 01:01:19.347 2602-2602/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa62a0288)
08-29 01:01:19.347 2602-2602/? E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.Error: Error copying database
        at so52053932.so52053932.DataBaseHandler.createDataBase(DataBaseHandler.java:67)
        at so52053932.so52053932.DAO.<init>(DAO.java:17)
        at so52053932.so52053932.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
  • Было 3 исключения (середина, которая появляется как 2-ая, печатает трассировку стека, когда последнее исключение было поймано / захвачено).
  • Первое исключение не является ФАТАЛЬНЫМ и является таким, как описано выше (т.е. ожидаемое исключение из метода checkDB)
  • Второе исключение является фактическим исключением, вызывающим проблему. Тем не менее, он был захвачен (и из-за того, что был напечатан дополнительный код, поэтому он не будет отображаться в вашем коде, так как он не печатается), в этом случае это связано с тем, что файл ресурса не найден (т. Е. Код ожидая FlagsQuiz не FlagsQuiz.txt или FlagsQuixk.NOTADB ).
  • Третье исключение соответствует throw new Error("Error copying database"); в методе createDatabase. (Не очень полезно, поскольку в вашем коде реальная причина / позиция в коде скрыта).

ПРИМЕЧАНИЕ На данном этапе базовая база данных фактически создана. **

согласно 08-29 01:01:19.339 2602-2602/? D/ONCREATE: New Database has been created so ONCREATE has been invoked.

например. Device Explorer показывает: -

Таким образом, последующий запуск не будет пытаться скопировать базу данных из активов, поскольку она существует. Однако , база данных, которая существует, НЕ будет иметь никаких таблиц, кроме sqlite_master и android_metadata . То есть, по сути, база данных пуста с точки зрения приложения (вы ожидаете по крайней мере 16 КБ (если я правильно помню) как еще одну страницу 4 КБ для любой другой таблицы)).

enter image description here

Поэтому, по-видимому, ваша настоящая проблема - это другая проблема. Возможно, я бы предложил изменить ваш код, чтобы включить временную отладку согласно (см. // <<<<< </strong> комментарии): -

DAO.java

public class DAO {

    DataBaseHandler dbHandler;

    public DAO(Context context) {
        dbHandler = new DataBaseHandler(context);
        try {

            dbHandler.createDataBase();

        } catch (IOException ioe) {

            throw new Error("Unable to create database");

        }
        try {

            dbHandler.openDataBase();
            Log.d("DAO","Attempting to open the database."); //<<<<< ADDED

        } catch (SQLException sqle) {
            Log.d("DAOCONSTRUCTOR","Error attempting to Open Database."); //<<<<< ADDED
            sqle.printStackTrace(); //<<<<< ADDED
            throw sqle;
        }
        // Log.e("path2",
        // context.getDatabasePath("FootballFlagQuiz").toString());
    }
}

DataBaseHandler.java

public class DataBaseHandler extends SQLiteOpenHelper {

    // The Androids default system path of your application database.
    private static String DB_PATH;

    private static String DB_NAME = "FlagsQuiz";

    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 DataBaseHandler(Context context) {

        super(context, DB_NAME, null, 1);
        this.myContext = context;
        DB_PATH = context.getDatabasePath(DB_NAME).toString();
//      Log.e("path", DB_PATH);
    }

    // ==============================================================================

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

        boolean dbExist = checkDataBase();

        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.
            this.getReadableDatabase();

            try {

                copyDataBase();

            } catch (IOException e) {
                e.printStackTrace(); //<<<<< ADDED

                throw new Error("Error copying database");

            }
        }

    }

    // ==============================================================================

    /**
     * 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;
            Log.d("CHKDB","Issuing openDatabase for path :- " + myPath); //<<<<< ADDED
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
            boolean checkresult = checkDB != null; //<<<<< ADDED
            Log.d("CHKDB", "Result of check is " + String.valueOf(checkresult)); //<<<<< ADDED

        } catch (SQLiteException e) {
            Log.d("CHECKDB", "SQLiteException has bee caught."); //<<<<< ADDED

            // database does't exist yet.

        }

        if (checkDB != null) {
            Log.d("CHECKDB","DB exists so closing the opened DB."); //<<<<< ADDED
            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 {

        Log.d("CPYDB","Database Copy Initiated. Trying to open InputStream i.e. asset " + "database/" + DB_NAME); //<<<<< ADDED

        // Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open("database/" + DB_NAME);
        Log.d("CPYDB","InputStream Opened successfully. Now trying to open OutputStream path = " + DB_PATH); //<<<<< ADDED

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

        // Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);
        Log.d("CPYDB","OutputStream Opened successfully. Now trying to copy from InputStream to OutputStream."); //<<<<< ADDED

        // 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);
            Log.d("CPYDB","Copied " + String.valueOf(length) + " bytes."); //<<<<< ADDED
        }
        Log.d("CPYDB","Completed Copy from asset to DB. Flusing and closing Streams"); //<<<<< ADDED

        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
        Log.d("CPYDB","Copy complete and all sterams flushed and closed. Copied " + String.valueOf(length) + "bytes."); //<<<<< ADDED
    }

    // ==============================================================================

    public void openDataBase() throws SQLException {

        // Open the database
        String myPath = DB_PATH;
        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) {
        Log.d("ONCREATE","New Database has been created so ONCREATE has been invoked."); //<<<<< ADDED

    }

    // ==============================================================================

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    // Add your public helper methods to access and get content from the
    // database.
    // You could return cursors by doing "return myDataBase.query(....)" so it'd
    // be easy
    // to you to create adapters for your views.

}

С учетом вышеуказанных изменений и, возможно, лучшего понимания трассировки стека вы сможете точно определить реальную ошибку (и), с которой вы столкнулись.


Действительный прогон

Запуск вашего кода с действительной БД в файле ресурсов и использование следующего в качестве (вызывающего) MainActivity: -

public class MainActivity extends AppCompatActivity {

    DAO myDAO;
    DataBaseHandler myDBhandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myDAO = new DAO(this);
        myDBhandler = myDAO.dbHandler;
        SQLiteDatabase db = myDBhandler.getWritableDatabase();
        Cursor csr = db.query("sqlite_master",null,null,null,null,null,null);
        while (csr.moveToNext()) {
            Log.d("COMPONENTS","Found " + csr.getString(csr.getColumnIndex("name")) + " Type is " + csr.getString(csr.getColumnIndex("type")));
        }
        csr.close();
    }
}

Результат: -

08-29 01:14:06.139 2699-2699/? D/CHKDB: Issuing openDatabase for path :- /data/data/so52053932.so52053932/databases/FlagsQuiz
08-29 01:14:06.139 2699-2699/? E/SQLiteLog: (14) cannot open file at line 30174 of [00bb9c9ce4]
    (14) os_unix.c:30174: (2) open(/data/data/so52053932.so52053932/databases/FlagsQuiz) - 
08-29 01:14:06.139 2699-2699/? E/SQLiteDatabase: Failed to open database '/data/data/so52053932.so52053932/databases/FlagsQuiz'.
    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:209)
        at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
        at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
        at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
        at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
        at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
        at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
        at so52053932.so52053932.DataBaseHandler.checkDataBase(DataBaseHandler.java:89)
        at so52053932.so52053932.DataBaseHandler.createDataBase(DataBaseHandler.java:48)
        at so52053932.so52053932.DAO.<init>(DAO.java:17)
        at so52053932.so52053932.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:5008)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
        at android.app.ActivityThread.access$600(ActivityThread.java:130)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
08-29 01:14:06.139 2699-2699/? D/CHECKDB: SQLiteException has bee caught.
08-29 01:14:06.151 2699-2699/? D/ONCREATE: New Database has been created so ONCREATE has been invoked.
08-29 01:14:06.151 2699-2699/? D/CPYDB: Database Copy Initiated. Trying to open InputStream i.e. asset database/FlagsQuiz
    InputStream Opened successfully. Now trying to open OutputStream path = /data/data/so52053932.so52053932/databases/FlagsQuiz
    OutputStream Opened successfully. Now trying to copy from InputStream to OutputStream.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Copied 1024 bytes.
    Completed Copy from asset to DB. Flusing and closing Streams
    Copy complete and all sterams flushed and closed. Copied -1bytes.
08-29 01:14:06.151 2699-2699/? D/DAO: Attempting to open the database.
08-29 01:14:06.159 2699-2699/? D/COMPONENTS: Found android_metadata Type is table
    Found PrivateList Type is table
    Found PrivateProduct Type is table
    Found List_Product Type is table
    Found sqlite_autoindex_List_Product_1 Type is index

Альтернативная проверка БД

Следующий код представляет собой альтернативный метод, который проверяет, существует ли БД (предполагается, что она является действительной БД) без выдачи SQLiteException. то есть он проверяет файл БД, а не БД ( он также не будет создавать пустую базу данных в случае сбоя копирования ): -

private boolean ifDatabaseExists(String dbpath) {
    File db = new File(dbpath);
    if(db.exists()) return true;
    File dir = new File(db.getParent());
    if (!dir.exists()) {
        dir.mkdirs();
    }
    return false;
}
  • это можно использовать в качестве альтернативы методу checkDB.
0 голосов
/ 28 августа 2018

Исходя из вашего кода, это ожидается. Это вызывает исключение в open в checkDatabase. Это говорит, что файл БД еще не существует. Если это новая установка, это будет правдой. Вы даже пытаетесь ожидать этого - см. Ваше заявление об улове? Вот как вы говорите, если БД новый.

Здесь нет ничего плохого. Это распечатает в первый раз на любом устройстве, и это все еще будет работать. Если вы хотите избавиться от сообщения, уберите запись из вашего оператора catch.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...