Результат резервного копирования базы данных Share Room в неподдерживаемый или пустой файл - PullRequest
0 голосов
/ 26 мая 2020

Я работаю над функцией резервного копирования для своего приложения, которая работает следующим образом: база данных комнаты сохраняется в файле в папке приложения (в соответствии с новыми рекомендациями Q и без запроса разрешения), а сам файл является общим. сразу после резервного копирования, чтобы пользователь мог сохранить или отправить куда-нибудь. Этот последний шаг необходим, чтобы избежать потери резервной копии, поскольку при удалении приложения резервная копия исчезает, и не каждый пользователь вручную переместит ее в другое место. Вот код:

    // Export the room database to a file in Android/data/com.minar.app/files
    private fun exportDb(context: Context) {
        // Perform a checkpoint to empty the write ahead logging temporary files and avoid closing the entire db
        val eventDao = EventDatabase.getDataBase(context)!!.eventDao()
        eventDao.checkpoint(SimpleSQLiteQuery("pragma wal_checkpoint(full)"))

        val dbFile = context.getDatabasePath("appDB").absoluteFile
        val appDirectory = File(context.getExternalFilesDir(null)!!.absolutePath)
        val fileName: String = "appBackup_" + LocalDate.now()
        val fileFullPath: String = appDirectory.path + File.separator.toString() + fileName
        // Toasts need the ui thread to work, so they must be forced on that thread
        try {
            dbFile.copyTo(File(fileFullPath), true)
            (context as MainActivity).runOnUiThread { Toast.makeText(context, context.getString(R.string.export_success), Toast.LENGTH_SHORT).show() }
        }
        catch (e: Exception) {
            (context as MainActivity).runOnUiThread { Toast.makeText(context, context.getString(R.string.export_failure), Toast.LENGTH_SHORT).show() }
            e.printStackTrace()
        }
        return fileFullPath
    }

    // Share the backup to a supported app
    private fun shareBackup(fileUri: String) {
        val shareIntent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_STREAM, Uri.parse(fileUri))
            type = "*/*"
        }

        // Verify that the intent will resolve to an activity
        if (shareIntent.resolveActivity(context.packageManager) != null)
            context.startActivity(shareIntent)
    }

Все, что я делаю, это вызываю эти функции, используя вывод первой во второй, но когда я делюсь файлом где-нибудь (например, в Gmail), все, что я получаю, это «не могу прикрепить пустой файл». Резервное копирование работает правильно, так как я могу открыть файл в любом средстве просмотра SQLite. Итак, мои вопросы следующие:

  • Эта проблема вызвана именем файла без расширения? Или это проблема Ури? Вероятно, второе, но почему?
  • Как я могу правильно проверить во время восстановления, является ли выбранный файл правильной резервной копией (это второстепенный вопрос, но я был бы признателен за предложение)

1 Ответ

0 голосов
/ 06 июня 2020

Попробуйте это:

Вы можете поместить файлы в каталог, производный от Environment.getExternalStorageDirectory (). Эти файлы сохранятся после удаления. Однако пользователь может удалить эти файлы в любое время, независимо от того, установлено ли ваше приложение или нет.

Сохранять файлы после удаления android приложения

...