我想在我的应用程序中实现地理围栏,但是需要支持根据这些地理围栏与用户的接近程度来进行过滤。
在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文件夹中,从而将输出添加到我的项目中。
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的自定义实现,它是使用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);
}
}
无法打开数据库。
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
SELECT
或INPUT
命令之后)关闭数据库。通过try - finally
实施。WRITE_EXTERNAL_STORAGE
权限。我忘记了什么吗?使用自定义扩展编译SQLite库时,我需要验证哪些内容并了解这些内容? 我的问题的根源是什么?