Резервное копирование и восстановление файла бд SQLite на андроид (kotlin)
Делаю небольшую программу с sqlite, мне нужно чтобы можно было базу данных сохранить а затем при необходимости загрузить снова. Я новичок в программировании, поэтому все дается трудно. После длительного поиска получился вот такой код, база вроде сохраняется в папке загрузки, но не могу ее потом загрузить обратно в sqlite, и при выбора файла не получается отфильтровать по расширению. Не понимаю как сохранить файл обратно в бд по uri.
private fun saveDb() { // сохранение бд в папке загрузка
val cursor = sqliteServer.query("PRAGMA wal_checkpoint(FULL);",null)
cursor.moveToFirst()
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "AS")
}
val dstUri = applicationContext.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
if (dstUri != null) {
val src = FileInputStream(applicationContext.getDatabasePath("AS"))
val dst = dstUri.let { applicationContext.contentResolver.openOutputStream(it) }
src.copyTo(dst!!)
src.close()
dst.close()
showToast("База сохранена в папке ,Загрузка, на устройстве")
} else showToast("Не удалось сохранить базу данных")
}
private fun dialogOpenFile(){ // Диалог выбора файла бд
val intent = Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT)
startActivityForResult(Intent.createChooser(intent, "Выберите файл базы данных"), 1)
}
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if ((requestCode == 1) && (resultCode == RESULT_OK)) {
val selectedFilename = data?.data
restoreDatabase(selectedFilename!!)
}
}
private fun restoreDatabase(uri: Uri) { // замена файла
try {
sqliteServer.close() // Close app database
val dbpath = sqliteServer.openHelper.readableDatabase.path
val dbFile = File(dbpath!!)
val bkpFile = uri.path?.let { File(it) }
bkpFile!!.copyTo(dbFile, true)
} catch (e: IOException) {
showToast(e.toString())
}
}
Ответы (1 шт):
Автор решения: woesss
→ Ссылка
uri.path
не является реальным путём файла и даже если бы он был таковым у вашего приложения нет к нему прямого доступа. Вы должны так же как и при сохранении получить поток через ContentResolver
:
private fun restoreDatabase(uri: Uri) { // замена файла
try {
sqliteServer.close() // Close app database
val dbpath = sqliteSever.openHelper.readableDatabase.path
applicationContext.contentResolver.openInputStream(uri)!!.use { bkpStream ->
FileOutputStream(dbpath!!).use { bkpStream.copyTo(it) }
}
} catch (e: IOException) {
showToast(e.toString())
}
}