E/SQLiteLog:(1)没有这样的表:Android 9 Pie上的汽车 [英] E/SQLiteLog: (1) no such table: Cars on Android 9 Pie

查看:410
本文介绍了E/SQLiteLog:(1)没有这样的表:Android 9 Pie上的汽车的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么数据库应对不适用于Android 9?我的实现基于以下示例(

Why does the coping of database not work for Android 9? My implementation is based on this example (video). Everything works fine on Android versions from 4.1 up to 10, but NOT on 9 Pie.

这是我所做的:

fun importToApp(fileNameOnSD: String) {
        val sd = File(sdFolder)
        if (sd.canWrite()) {
            val currentDB = File(Environment.getDataDirectory(), dataTemp)
            val backupDB = File(sd, fileNameOnSD)
            if (currentDB.exists()) {
                try {
                    val src = FileInputStream(backupDB).channel
                    val dst = FileOutputStream(currentDB).channel
                    dst.transferFrom(src, 0, src.size())
                    src.close()
                    dst.close()
                } catch (e: FileNotFoundException) {
                    e.printStackTrace()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        copyData()
    }

    private fun copyData() {
        db.delete(TABLE, null, null)
        val dbBackup = context.openOrCreateDatabase(DB_TEMP, Context.MODE_PRIVATE, null)
        val cursor = dbBackup.query(true, TABLE, null, null, null, null, null, null, null)

        cursor.moveToFirst()
        while (!cursor.isAfterLast) {
            db.insert(TABLE, null, modelToValues(cursorToModel(cursor)))
            cursor.moveToNext()
        }
        cursor.close()
        context.deleteDatabase(dataTemp)
        utilities.toast(context.resources.getString(R.string.db_suc_imported), 0)
    } 

我也调用该方法(在此提出):

override fun onOpen(db: SQLiteDatabase) {
        super.onOpen(db)
        if (Build.VERSION.SDK_INT == 28)
            db.disableWriteAheadLogging()
    }

这是在Android Pie中引起的崩溃:

Here is the crash caused in Android Pie:

E/SQLiteLog: (1) no such table: Cars 
D/AndroidRuntime: Shutting down VM


    --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.easyapps.cryptnote, PID: 3174
    android.database.sqlite.SQLiteException: no such table: Cars (code 1 SQLITE_ERROR): , while compiling: SELECT DISTINCT * FROM Cars 
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)
        at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1255)
        at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1126)
        at com.easyapps.cryptnote.ListDatabase.copyData(CarsDatabase.kt:144)
        at com.easyapps.cryptnote.ListDatabase.importToApp(CarsDatabase.kt:137)
        at com.easyapps.cryptnote.ImportActivity$importDB$$inlined$apply$lambda$1.onClick(CarsActivity.kt:273)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 3174 SIG: 9

此行val cursor = dbBackup.query(true, TABLE, null, null, null, null, null, null, null)使应用程序崩溃.到目前为止,我已经在两种不同的真实Android设备上进行了测试,一种使用Android Lollipop(Moto),另一种使用Android Pie(Samsung A40).其他版本是虚拟的.最有趣的是,它可以在具有Android Pie的Samsung上运行,但不能在具有Android Pie的虚拟设备上运行.尽管如此,我认为三星设备是例外,我需要在所有Android设备上运行,无论是真实的还是虚拟的.

This line val cursor = dbBackup.query(true, TABLE, null, null, null, null, null, null, null) crashes the app. So far I tested in on two different real Android devices, one with Android Lollipop (Moto) and one with Android Pie (Samsung A40). The other versions were virtual. The most interesting thing is that it works on Samsung with Android Pie, but not on a virtual device with Android Pie. Nevertheless, I assume that is the Samsung device is exception, I need to get run on all Android devices, no matter real or virtual.

推荐答案

因此,我通过使用第一个

So, I fixed the issue by using the first answer. I added an internal class

class TempDataBase(private val context: Context, dbName: String, version: Int) : SQLiteOpenHelper(
        context,
        dbName, null,
        version
    ) {
        override fun onCreate(db: SQLiteDatabase) {
            db.execSQL("CREATE TABLE $TABLE ($ID INTEGER PRIMARY KEY AUTOINCREMENT, $TITLE TEXT, $NOTE TEXT, $DATE TEXT);")
        }

        override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
            db.execSQL("DROP TABLE IF EXISTS $TABLE")
            onCreate(db)
        }

        override fun onConfigure(db: SQLiteDatabase) {
            db.disableWriteAheadLogging()
            super.onConfigure(db)
        }
    }

并在我的copyData()方法中调用它:

and called it in my copyData() method:

private fun copyData() {
        db.delete(TABLE, null, null)
        val dbBackup = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
            SQLiteDatabase.openDatabase(TempDataBase(context, DB_TEMP, 1).readableDatabase.path, null, SQLiteDatabase.OPEN_READWRITE)
        }
        else
            context.openOrCreateDatabase(DB_TEMP, Context.MODE_PRIVATE, null)
        val cursor = dbBackup.query(true, TABLE,null,null,null,null,null,null, null)
        cursor.moveToFirst()
        while (!cursor.isAfterLast) {
            db.insert(TABLE, null, modelToValues(cursorToModel(cursor)))
            cursor.moveToNext()
        }
        cursor.close()
        db.close()
        context.deleteDatabase(dataTemp)
        utilities.toast(context.resources.getString(R.string.db_suc_imported), 0)
    }

基本上,Android P查找数据库并检测到该数据库不存在,而其他版本并不真正要求临时数据库必须确实存在.我的内部类创建一个临时数据库作为缓冲区,以复制Android 9使用的数据.

Basically, Android P looks for a database and detects that is does not exist while other versions do not really require that a temp database must really exist. My inner class creates a temp database as buffer to copy data in used by Android 9.

无论谁还在寻找解决方案,请发表评论以获取更多信息,我将尽快答复.

Whoever still looking for a solution, please leave a comment for more info and I will respond asap.

这篇关于E/SQLiteLog:(1)没有这样的表:Android 9 Pie上的汽车的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆