无法使用自定义绑定打开SQLite数据库

时间:2018-09-05 15:53:45

标签: android sqlite

目标

我想在我的应用程序中实现地理围栏,但是需要支持根据这些地理围栏与用户的接近程度来进行过滤。

方法

已采取的步骤

在Android上,SQLite已禁用R * Tree模块。为了解决这个问题,您需要在项目中添加自己的SQLite库。

multiple options可以将Android绑定添加到自定义SQLite库中。

第一个选项不适合我的需求,添加源代码是不得已的方法,它不能解决我当前的问题。 我选择了 second选项并通过将-DSQLITE_ENABLE_RTREE中的src/main/java/jni/sqlite/Android.mk设置为1来启用R * Tree模块:

# Enable SQLite extensions.
LOCAL_CFLAGS += -DSQLITE_ENABLE_FTS5 
LOCAL_CFLAGS += -DSQLITE_ENABLE_RTREE=1
LOCAL_CFLAGS += -DSQLITE_ENABLE_JSON1
LOCAL_CFLAGS += -DSQLITE_ENABLE_FTS3

我还执行了步骤3,并将.aar添加到我的libs文件夹中,从而将输出添加到我的项目中。

build.gradle

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
  // other dependencies
}

其他代码文件

导入已更新,并且库已加载,如this document定义。

令人反感的方法

这些方法用于与不使用R * Tree模块的现有表进行交互。

static List<LocationInterface> getSince(SQLiteDatabase database, long millisecondsSince1970) {
    if (database == null) {
        return null;
    }

    Cursor cursor = null;
    try {
        cursor = database.query(TABLE_NAME, null, LocationTable.COLUMN_CREATED_AT + " > " + millisecondsSince1970,
                null, null, null, LocationTable.COLUMN_CREATED_AT, QUERY_LIMIT);

        if (cursor == null || cursor.isClosed()) {
            return null;
        }

        // cursor is closed at the end of the function
        return getLocations(cursor);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
        database.close();
    }
}

static void deleteBefore(SQLiteDatabase database, long millisecondsSince1970) {
    database.delete(TABLE_NAME, LocationTable.COLUMN_CREATED_AT + " <= " + millisecondsSince1970, null);
    database.close();
}

private static List<LocationInterface> getLocations(Cursor cursor) {
    List<LocationInterface> locations = null;

    if (cursor.moveToFirst()) {
        locations = new ArrayList<>();
        do {
            if (cursor.isClosed()) {
                break;
            }

            // Creates a LocationInterface object, does not modify cursor
            locations.add(getLocationFromCursor(cursor));
        } while (cursor.moveToNext());
    }

    cursor.close();
    return locations;
}

使用的进口

import android.content.ContentValues;
import android.database.Cursor;
import org.sqlite.database.sqlite.SQLiteDatabase;
import org.sqlite.database.sqlite.SQLiteStatement;

SQLiteOpenHelper

有一个SQLiteOpenHelper的自定义实现,它是使用Singleton设计模式实现的。 我们正在使用该类,该类又使用第一个调用者的上下文的应用程序上下文来使我们对可写数据库具有可读性。

final class DatabaseHelper extends SQLiteOpenHelper {

    private static DatabaseHelper instance;
    private static final String DATABASE_NAME = "myDatabase.db";
    private static final int DATABASE_VERSION = 4;

    public static synchronized DatabaseHelper getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseHelper(context.getApplicationContext());
        }
        return instance;
    }

    private DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        LocationTable.createIfRequired(db);
        GeofenceContract.createIfRequired(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        LocationTable.upgrade(db, oldVersion, newVersion);
        GeofenceContract.upgrade(db, oldVersion, newVersion);
    }
}

问题

无法打开数据库。

Stacktrace

09-05 17:45:35.575 28508-28615/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:35.576 28508-28615/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:466)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:188)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:180)
    at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:810)
    at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:795)
    at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:698)
    at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:721)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:259)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:223)
    at com.example.sdk.core.ExampleDatabase.getSince(ExampleDatabase.java:64)
    at com.example.sdk.core.LocationDispatcher.postLocations(LocationDispatcher.java:41)
    at com.example.sdk.core.DispatchWorker.sendLocations(DispatchWorker.java:74)
    at com.example.sdk.core.DispatchWorker.doWork(DispatchWorker.java:49)
    at androidx.work.Worker.onStartWork(Worker.java:70)
    at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:195)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:117)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
09-05 17:45:35.625 28508-28615/com.example.android.demo E/SQLiteOpenHelper: Couldn\'t open myDatabase.db for writing (will try read-only):
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:466)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:188)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:180)
    at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:810)
    at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:795)
    at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:698)
    at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:721)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:259)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:223)
    at com.example.sdk.core.ExampleDatabase.getSince(ExampleDatabase.java:64)
    at com.example.sdk.core.LocationDispatcher.postLocations(LocationDispatcher.java:41)
    at com.example.sdk.core.DispatchWorker.sendLocations(DispatchWorker.java:74)
    at com.example.sdk.core.DispatchWorker.doWork(DispatchWorker.java:49)
    at androidx.work.Worker.onStartWork(Worker.java:70)
    at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:195)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:117)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
09-05 17:45:35.817 28508-28615/com.example.android.demo E/DispatchWorker: No locations sentserver
09-05 17:45:35.817 28508-28615/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:35.823 28508-28615/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:35.824 28508-28615/com.example.android.demo E/WorkerWrapper: Work [ id=2cc7ccee-72c9-4178-a6ce-891ef3696faa, tags={ Example_dispatch_work, com.example.sdk.core.DispatchWorker } ] failed because it threw an exception/error
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:466)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:188)
    at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:180)
    at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:810)
    at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:795)
    at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:698)
    at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:721)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:259)
    at org.sqlite.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:199)
    at com.example.sdk.core.ExampleDatabase.deleteBefore(ExampleDatabase.java:73)
    at com.example.sdk.core.DispatchWorker.sendLocations(DispatchWorker.java:96)
    at com.example.sdk.core.DispatchWorker.doWork(DispatchWorker.java:49)
    at androidx.work.Worker.onStartWork(Worker.java:70)
    at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:195)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:117)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
09-05 17:45:42.069 28508-28616/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:42.121 28508-28616/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:42.171 28508-28616/com.example.android.demo E/SQLiteOpenHelper: Couldn\'t open myDatabase.db for writing (will try read-only):
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:42.425 28508-28616/com.example.android.demo E/DispatchWorker: No locations sentserver
09-05 17:45:42.474 28508-28616/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:42.475 28508-28616/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:42.516 28508-28616/com.example.android.demo E/WorkerWrapper: Work [ id=2c27be2a-94c9-4bca-a63a-34133bb7e7dd, tags={ Example_dispatch_work, com.example.sdk.core.DispatchWorker } ] failed because it threw an exception/error
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:43.914 28508-28616/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:43.915 28508-28616/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:43.916 28508-28616/com.example.android.demo E/SQLiteOpenHelper: Couldn\'t open myDatabase.db for writing (will try read-only):
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:44.063 28508-28616/com.example.android.demo E/DispatchWorker: No locations sentserver
09-05 17:45:44.063 28508-28616/com.example.android.demo E/SQLiteLog: (14) cannot open file at line 37631 of [c7ee083322]
    (14) os_unix.c:37631: (2) open(//myDatabase.db) -
09-05 17:45:44.065 28508-28616/com.example.android.demo E/SQLiteDatabase: Failed to open database 'myDatabase.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
09-05 17:45:44.066 28508-28616/com.example.android.demo E/WorkerWrapper: Work [ id=d128fc77-b562-4da8-8a28-8e74d071f168, tags={ Example_dispatch_work, com.example.sdk.core.DispatchWorker } ] failed because it threw an exception/error
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
    at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
    at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)

尝试的解决方案

  • 使用libsqliteX代替要导入的库名sqliteX
  • 每次操作(SELECTINPUT命令之后)关闭数据库。通过try - finally实施。
  • 添加了WRITE_EXTERNAL_STORAGE权限。
  • 很多“干净的构建”
  • 再次重新编译SQLite库。

问题

我忘记了什么吗?使用自定义扩展编译SQLite库时,我需要验证哪些内容并了解这些内容? 我的问题的根源是什么?

0 个答案:

没有答案