2014-10-30 2 views
1

Моя цель - создать пользовательскую версию SQLite (в частности, с включенным R-Tree) для включения в мой Android-проект. Мотивация обусловлена:Android Custom SQLite Build - не удается открыть базу данных

Android SQLite R-Tree - How to install module?

SQLite имеет некоторые инструкции в том, как это сделать:

http://www.sqlite.org/android/doc/trunk/www/index.wiki

Я составил SQLite и успешно включали общую библиотеку в моем проекте. Проблема, с которой я сталкиваюсь, заключается в том, что как только я вызываю операцию, такую ​​как getReadableDatabase() или getWriteableDatabase() Я получаю исключение SQLiteCantOpenDatabaseException.

Важно отметить, что я использую:

import org.sqlite.database.sqlite.SQLiteDatabase;

import org.sqlite.database.sqlite.SQLiteOpenHelper;

вместо:

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

Для использования пользовательской сборки SQLite через NDK и JNI.

MySQLiteHelper:

public class MySQLiteHelper extends SQLiteOpenHelper { 

    static { 
     System.loadLibrary("sqliteX"); 
    } 

    private static final String DATABASE_NAME = "mydata.db"; 
    private static final int DATABASE_VERSION = 1; 
    Context myContext; 

    public MySQLiteHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     myContext = context; 
    } 

    public void getEntry(){ 
     SQLiteDatabase db = this.getReadableDatabase(); 
     db.close(); 
    } 

    public void createEntry(){ 
     // 1. get reference to writable DB 
     SQLiteDatabase db = this.getWritableDatabase(); 
     //... 
     //... 
     db.close(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase database) { 
     String create_rtree = "CREATE VIRTUAL TABLE demo_index USING rtree(\n" + 
       " id,    -- Integer primary key\n" + 
       " minX, maxX,  -- Minimum and maximum X coordinate\n" + 
       " minY, maxY  -- Minimum and maximum Y coordinate\n" + 
       ");"; 

     database.execSQL(create_rtree); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(MySQLiteHelper.class.getName(), 
      "Upgrading database from version " + oldVersion + " to " 
        + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS " + "demo_index"); 
     onCreate(db); 
    } 

} 

Основная деятельность:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    MySQLiteHelper helper = new MySQLiteHelper(this); 
    helper.createEntry(); 
    setContentView(R.layout.activity_my); 
} 

Трассировка стека:

10-29 13:45:38.356 2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteLog﹕ (14) os_unix.c:30589: (2) open(//arrrr.db) - 
10-29 13:45:38.376 2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteDatabase﹕ Failed to open database 'arrrr.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:217) 
     at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:201) 
     at  org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:467) 
     at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189) 
     at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181) 
     at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:809) 
     at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:794) 
     at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699) 
     at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:722) 
     at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:228) 
     at org.sqlite.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:168) 
     at com.example.nathanielwendt.lstrtree.MySQLiteHelper.createEntry(MySQLiteHelper.java:65) 
     at com.example.nathanielwendt.lstrtree.MyActivity.onCreate(MyActivity.java:25) 

Я видел несколько постов здесь на так об этом же исключения, но все они, как представляется, связаны с импорта к базе данных из другого места на диске, в котором они не установить путь к файлу правильно. Это, по-видимому, самый связанный пост: Android SQLiteOpenHelper cannot open database file, но ни один из предложений не работал.

Я пробовал это с двумя разными телефонами и с эмулятором, и я получаю ту же ошибку. Кроме того, я заменил импорт, о котором говорилось выше, с использованием импорта android sqlite по умолчанию и работает отлично (учитывая, что я не пытаюсь создать R-Tree, поскольку он не включен в стандартную установку Android SQLite по умолчанию). Изменение разрешений для файла dir и .db базы данных на 777 не помогло устранить проблему, и добавление WRITE_PERMISSION в мой манифест не добавило.

+0

На каком пути вы на самом деле пытаетесь получить доступ? –

ответ

4

Это несовместимость в привязках Android-приложений SQLite.

оригинальный Android код открывает базу данных, как это:

db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? 
     Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, 
     mFactory, mErrorHandler); 

пока org.sqlite.database.sqlite.SQLiteOpenHelper не использует контекст:

db = SQLiteDatabase.openOrCreateDatabase(
     mName, mFactory, mErrorHandler 
); 

Это означает, что путь к базе данных не предваряется в базу данных имя.

использовать что-то вроде этого, чтобы получить полный путь к базе данных:

String path = context.getDatabasePath(DATABASE_NAME).getPath(); 

и использовать его в качестве имени базы данных.

+0

Отлично работает, спасибо! –

Смежные вопросы