Не удается открыть базу данных SQLite с помощью пользовательских привязок - PullRequest
0 голосов
/ 05 сентября 2018

Цель

Я хочу реализовать геозону в своем приложении, но мне нужно поддерживать фильтрацию по этим геозонам на основе их близости к пользователю.

Подход

Шаги приняты

Модуль R * Tree отключен для SQLite на Android. Чтобы исправить это, вам нужно добавить собственную библиотеку SQLite в ваш проект.

Существует несколько вариантов для добавления привязок Android в пользовательскую библиотеку SQLite.

Первый вариант не отвечал моим потребностям, и добавление исходного кода является последним средством, которое не должно разрешать мои текущие проблемы. Я выбрал второй параметр и включил модуль R * Tree, установив -DSQLITE_ENABLE_RTREE в 1 в src/main/java/jni/sqlite/Android.mk:

# 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
}

другие файлы кода

Импорт был обновлен, и библиотека была загружена, как этот документ определяет.

Методы оскорбления

Эти методы используются для взаимодействия с уже существующей таблицей, в которой не используется модуль 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
  • Закрытая база данных после каждой операции (команда SELECT или INPUT). Применяется через try - finally.
  • Добавлено разрешение WRITE_EXTERNAL_STORAGE.
  • Много «чистых сборок»
  • Перекомпилирована библиотека SQLite снова.

Вопрос

Я что-то забыл? Что нужно проверить и знать при компиляции библиотеки SQLite с пользовательскими расширениями? В чем корень моей проблемы?

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