Android App Datei überschreibenauf Xiaomi Mi8 nicht möglich

jokakilla

Lt. Junior Grade
Registriert
Dez. 2007
Beiträge
308
Hallo zusammen,
ich habe seit einiger Zeit eine App im Playstore. Diese bietet die möglichkeit die internen Daten zu sichern und wiederherzustellen.

Beim wiederherstellen wird (Holzhammermethode) die SQLite Datenbank überschrieben.
Das hat bisher auf sehr unterschiedlichen Geräten (Simulator, Sony Z1 Compact, verschiedene Samsung Galaxy, Huawei P9, Honor, ...) sehr gut funktioniert. Jetzt habe ich allerdings ein Xiaomi Mi8 und dort lässt sich das Backup nicht einspielen.

Ich habe verschiedene Varianten zum Kopieren getestet (Stream, Files.copy, und jetzt mit Apache Commons IO FileUtils.copyFile) aber die Datenbank Datei ist nach dem Kopieren immer unverändert. Die Checksum vor und nach dem Kopieren ist immer die gleiche. Auf anderen Geräten ist sie erwartungsgemäß unterschiedlich.

long crc = FileUtils.checksumCRC32( new File( getReadableDatabase().getPath() ) ); //z.B. 123
FileUtils.copyFile( new File( backupFilename ), new File( getReadableDatabase().getPath() ) );
crc = FileUtils.checksumCRC32( new File( getReadableDatabase().getPath() ) ); //Immernoch 123

Der Datenbankpfad (getReadableDatabase().getPath()/getWritableDatabase().getPath()) ist /data/user/0/de.jokakilla.cloud.batterymanager/databases/batteries


Ich weiß das überschreiben der Datei ist nicht der beste Weg aber ich wollte auf komplexe Mechanismen serialisierung/deserialisierung usw. verzichten. Ohne Transaktionen und Write Ahead Logging dürfte das eigentlich auch einigermaßen unkritisch sein und es hat jetzt 1,5 Jahre auf verschiedensten Systemen gut funktioniert.
 
Gerade habe ich noch festgestellt dass das Problem scheinbar mit Android 9 zusammenhängt. Im Emulator mit einem Android 9 tritt das Problem auf. Im gleichen Emulator bloß mit 8.1 nicht. Hat jemand eine Idee was sich dort geändert haben kann?
 
Bei dir war das deaktivieren des WAL die Loesung? Weil es gab ja auch noch andere Antwort darueber, wo wohl eine offen DB Verbindung das Problem war.
 
Ja das war die Lösung.
Im SQLiteOpenHelper musste nur onOpen überschrieben werden.
@Override
public void onOpen( SQLiteDatabase db ) {
super.onOpen(db);
db.disableWriteAheadLogging();
}

Das close auf die Verbindung habe ich vorher auch schon versucht. Auch ohne die Lösung lieferten die folgenden drei Anweisungen alle false zurück:
database.isWriteAheadLoggingEnabled()
database.inTransaction()
database.isOpen()

So ganz nachvollziehen kann ich das nicht aber nehme die Lösung so hin.
 
Ok, ja WAL aktiviert ändert wohl einiges, siehe hier

Kleine Anmerkung noch, mach es so wie im Comment unter der Antwort dann, also nutze die Methode onConfigure die ist explizit dafür vorgesehen u.a. den WAL zu deaktivieren
onConfigure

Added in API level 16
public void onConfigure (SQLiteDatabase db)

Called when the database connection is being configured, to enable features such as write-ahead logging or foreign key support.
This method is called before onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int), onDowngrade(SQLiteDatabase, int, int), or onOpen(SQLiteDatabase) are called. It should not modify the database except to configure the database connection as required.

This method should only call methods that configure the parameters of the database connection, such as SQLiteDatabase#enableWriteAheadLogging SQLiteDatabase#setForeignKeyConstraintsEnabled, SQLiteDatabase#setLocale, SQLiteDatabase#setMaximumSize, or executing PRAGMA statements.
 
Zurück
Oben