Невозможно прочитать данные из базы данных после копирования внешней базы данных во внутреннюю базу данных android - PullRequest
0 голосов
/ 23 января 2020

Я пытался скопировать внешнюю базу данных в базу данных телефона, используя следующий код

    /**
     * Populates database with existing database.
     */
    fun installDatabaseFromAssets() {
        val inputStream = context.assets.open("$ASSETS_PATH/$DATABASE_NAME.sqlite3")

        try {
            val outputFile = File(context.getDatabasePath(DATABASE_NAME).path)
            val outputStream = FileOutputStream(outputFile)

            inputStream.copyTo(outputStream)
            inputStream.close()

            outputStream.flush()
            outputStream.close()
        } catch (exception: Throwable) {
            throw RuntimeException("The $DATABASE_NAME database couldn't be installed.", exception)
        }
    }

, как описано в https://medium.com/@johann.pardanaud / ship-an- android -app-with-a -pre-populated-database-cd2b3aa3311f . Я также переименовал свой столбец sqlite db id в _ID, как рекомендовано в статье. Данные копируются нормально, но когда я пытаюсь прочитать их с помощью приложения, они выдают следующие ошибки

01-23 16:36:13.808 31146-31165/com.lonewolf.rj.myapp E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 19407 rows, 8 columns.
01-23 16:36:13.808 31146-31165/com.lonewolf.rj.myapp W/dalvikvm: threadid=12: thread exiting with uncaught exception (group=0x41632d58)
01-23 16:36:13.808 31146-31165/com.lonewolf.rj.myapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.lonewolf.rj.myapp, PID: 31146
    java.lang.RuntimeException: An error occured while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:300)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
        at java.util.concurrent.FutureTask.run(FutureTask.java:242)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:841)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:437)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at com.lonewolf.rj.myapp.DatabaseHelper.readData(DatabaseHelper.kt:101)
        at com.lonewolf.rj.myapp.MainActivity$DbWork.doInBackground(MainActivity.kt:46)
        at com.lonewolf.rj.myapp.MainActivity$DbWork.doInBackground(MainActivity.kt:42)
        at android.os.AsyncTask$2.call(AsyncTask.java:288)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
        at java.lang.Thread.run(Thread.java:841) 

Как я могу исправить эту проблему и сделать читаемую базу данных доступной для чтения? и если есть какие-либо android специфицированные c столбцы, которые должны существовать в БД?

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Сообщение

Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

скажем не найден столбец, если используется cursor.getColumnIndex("column_name") получение -1 , если column_name не столбец в курсоре ,

use 0 not cursor.getColumnIndex("column_name") сначала получает столбец в Cursor.

способ просмотреть все Cursor, используя DatabaseUtils.dumpCursor(cursor); все идет в журнал.

0 голосов
/ 23 января 2020

Выполните шаги 1. Скопируйте базу данных из внутреннего хранилища и создайте тот же файл имени БД во внешнем хранилище
2. Теперь, после проверки, существует ли внешнее хранилище, скопируйте базу данных и перейдите во внутреннее хранилище

copyDataBseToExternal ( internalDBFilePath, DB_NAME, ExternalDBFilePath)

copyDataBseFromExternal (ExternalDBFilePath, DB_NAME, InternalDbFilePath)

// Копировать базу данных с SD-карты во внутреннюю папку приложения

веселое копирование DataBataFrom: inputFile: String, outputPath: String)

{

    var ins: InputStream? = null

    var out: OutputStream? = null

    try {
        //create output directory if it doesn't exist
        val dir = File(outputPath)
        if (!dir.exists()) {
            dir.mkdirs()
        }
        ins = FileInputStream(inputPath)
        out = FileOutputStream(outputPath)
        val buffer = ByteArray(1024)
        var length = ins.read(buffer)
        // read = `in`.read(buffer)
        while (length > 0) {
            //out.write(buffer, 0, read)
            out.write(buffer, 0, length)
            length = ins.read(buffer)
        }
        ins.close()

        // write the output file
        out.flush()
        out.close()
        // delete the original file
        // File(inputPath + inputFile).delete()
    } catch (fnfe1: FileNotFoundException) {
        Log.e("tag", fnfe1.message)
    } catch (e: Exception) {
        Log.e("tag", e.message)
    }
}

publi c fun copyDataBseToExternal (inputPath: String, inputFile: String, outputPath: String)

{

   var ins: InputStream? = null

    var out: OutputStream? = null

  try {
        //create output directory if it doesn't exist
        val dir = File(outputPath)
        if (!dir.exists()) {
            dir.mkdirs()
        }
        ins = FileInputStream(inputPath)
        out = FileOutputStream(outputPath + "/" + inputFile)
        val buffer = ByteArray(1024)
        var length = ins.read(buffer)
        // read = `in`.read(buffer)
        while (length > 0) {
            //out.write(buffer, 0, read)
            out.write(buffer, 0, length)
            length = ins.read(buffer)
        }
        ins.close()

        // write the output file
        out.flush()
        out.close()
        // delete the original file
        // File(inputPath + inputFile).delete()
    } catch (fnfe1: FileNotFoundException) {
        Log.e("tag", fnfe1.message)
    } catch (e: Exception) {
        Log.e("tag", e.message)
    }
}
...