Ответ 1
Я видел эту ошибку, если вы используете sharedUserId в своем манифесте. Если вы измените sharedUserId приложения и переустановите приложение, у него нет требуемого права собственности на запись в базу данных SQLite.
Я пытаюсь скопировать существующую базу данных из папки моих ресурсов и выполнить некоторые операции над ней. Все работает нормально, но я получил следующую ошибку в файлах журнала моего эмулятора:
sqlite returned: error code = 14, msg = cannot open file at source line 25467
09-06 11:23:41.844: INFO/Database(22560): sqlite returned: error code = 14, msg = cannot open file at source line 25467
09-06 11:23:41.885: ERROR/Database(22560): sqlite3_open_v2("/data/data/com.dhani.Lazy/databases/LazyDB.sqlite", &handle, 1, NULL) failed
09-06 11:23:41.885: WARN/System.err(22560): android.database.sqlite.SQLiteException: unable to open database file
09-06 11:23:41.894: WARN/System.err(22560): at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
09-06 11:23:41.904: WARN/System.err(22560): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1849)
09-06 11:23:41.914: WARN/System.err(22560): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
09-06 11:23:41.914: WARN/System.err(22560): at com.dharani.LazyApple.Database.DataBaseHelper.checkDataBase(DataBaseHelper.java:72)
09-06 11:23:41.914: WARN/System.err(22560): at com.dharani.LazyApple.Database.DataBaseHelper.createDataBase(DataBaseHelper.java:47)
09-06 11:23:41.914: WARN/System.err(22560): at com.dharani.LazyApple.Database.DataBaseHelper.Login(DataBaseHelper.java:166)
09-06 11:23:41.914: WARN/System.err(22560): at com.dharani.LazyApple.Views.LoginView$1.onClick(LoginView.java:63)
09-06 11:23:41.934: WARN/System.err(22560): at android.view.View.performClick(View.java:2485)
09-06 11:23:41.934: WARN/System.err(22560): at android.view.View$PerformClick.run(View.java:9080)
09-06 11:23:41.944: WARN/System.err(22560): at android.os.Handler.handleCallback(Handler.java:587)
09-06 11:23:41.944: WARN/System.err(22560): at android.os.Handler.dispatchMessage(Handler.java:92)
09-06 11:23:41.944: WARN/System.err(22560): at android.os.Looper.loop(Looper.java:123)
09-06 11:23:41.944: WARN/System.err(22560): at android.app.ActivityThread.main(ActivityThread.java:3683)
09-06 11:23:41.964: WARN/System.err(22560): at java.lang.reflect.Method.invokeNative(Native Method)
09-06 11:23:41.964: WARN/System.err(22560): at java.lang.reflect.Method.invoke(Method.java:507)
09-06 11:23:41.964: WARN/System.err(22560): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
09-06 11:23:41.964: WARN/System.err(22560): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
09-06 11:23:41.964: WARN/System.err(22560): at dalvik.system.NativeStart.main(Native Method)
Любые предложения по решению этой проблемы?
Я видел эту ошибку, если вы используете sharedUserId в своем манифесте. Если вы измените sharedUserId приложения и переустановите приложение, у него нет требуемого права собственности на запись в базу данных SQLite.
Это может быть немного поздно, но надеюсь, что это поможет тем, кто получит эту проблему (так как я не могу найти окончательное решение).
Я думаю, что знаю причину этой причины (по крайней мере, для моего случая). Если вы посмотрите в DDMS → Проводнике, вы поймете, что Папка базы данных (/data/data//databases/) не существует, поэтому приложение не может создать файл базы данных в этой несуществующей папке. Если вы можете каким-то образом создать папку с базами данных, вы можете избежать этой проблемы.
Поскольку я ленив, я просто использовал /data/data//файлы/папку, когда я в режиме эмулятора. Вы можете получить файлы dir, используя это:
context.getFilesDir().getPath()
Это прекрасно работало для меня в эмуляторе.
Надеюсь, это поможет кому-то.
Если вы хотите увидеть какой-то код:
String dbFilename = "example.db";
try
{
File databaseFile = getDatabasePath(dbFilename);
SQLiteDatabase _db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
} catch (Exception e)
{
String databasePath = getFilesDir().getPath() + "/" + dbFilename;
File databaseFile = new File(databasePath);
_db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
}
EDIT: я попытался войти в Facebook (мое приложение интегрировало FB) в папку Emulator и /databases появилось после этого (и продолжалось). Не знаю, что произошло, но возможно создать такую папку. Что-то для другого эксперта здесь, чтобы пролить свет.
Сегодня этот вопрос стоил мне 3 часа. Что я пробовал:
Я решил проблему, скопировав код из общей учетной записи Dropbox в другое место и рефакторинг кода в Android Manifest и java файлах с другим именем пакета.
Приложение работает красиво сейчас.
У меня была та же проблема.
Что его решило, заменил
private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
с
String myPath = myContext.getFilesDir().getAbsolutePath().replace("files",
"databases")+File.separator + DB_NAME;
У меня был тот же код ошибки в logcat:
sqlite returned: error code = 14, msg = cannot open file at source line
Приложение будет работать нормально (на самом деле я не заметил никаких проблем, пока не посмотрел на logcat!). Logcat сообщил мне об этой ошибке, поэтому я подумал, что лучше всего решить эту проблему.
Оказывается, если бы я отредактировал файл манифеста, он избавился от ошибки! В моем манифесте я набрал неверную версию min sdk. Я обнаружил это, потому что в файле манифеста появился восклицательный знак вдоль левого столбца кода, информирующий меня о моей ошибке.
Чтобы быть тщательным, я бы рекомендовал вам убедиться, что все ошибки/восклицания исправлены, поэтому вы можете, по крайней мере, исключить их.
Кажется, эта ошибка (и многое другое в затмении) может произойти в зависимости от огромного числа факторов! О, радости!
Или другое облегченное решение для меня:
Моя причина была другая: я получил доступ к онлайн-версии приложения, которое создало базу данных. Приложение PhoneGap не могло получить доступ к файлу, созданному в другом приложении. Очистка кеша браузера решила мою проблему.
Энигма решена, протестирована в эмуляторе без БД и помечена неверно, поэтому сначала нужно создать БД
InputStream myInput = myContext.getAssets().open(DB_NAME);
//Destination folder (where we created the DB empty)
String outFileName = DB_PATH + DB_NAME;
//We opened it BBDD Vacia as OutputStream
OutputStream myOutput = new FileOutputStream(outFileName);
//Transfers Bytes between input and output Stream
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the open files
myOutput.flush();
myOutput.close();
myInput.close();
}
После этого выполните свои операции. Удачи!
Мне удалось решить это, осознав, что документация немного вводит в заблуждение. Вам нужно иметь имя файла для вашего zip-ресурса, связанного с именем вашей базы данных. Например, если ваша база данных называется someData.db
, ваш zip файл должен быть someData.zip
.
Кроме того, кажется, что есть немного лучшая диагностика, если вы попытаетесь открыть записываемый db. Я сделал это в конструкторе, следующим образом, что в конечном итоге помогло мне разобраться в решении.
SQLiteDatabase db=getWritableDatabase();
db.close();
Убедитесь, что вы закрываете все ваши курсоры и экземпляры db. У меня была эта ошибка из-за создания нескольких вложений и обновлений, а не закрытия курсоров, вызывая утечку курсора и не удалось открыть db.