导出房间数据库并附加到Android Kotlin电子邮件

本教程将介绍导出房间数据库并附加到Android Kotlin电子邮件的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

问题描述

我有以下代码,用于导出聊天室数据库,然后将其附加到电子邮件。当前,用户必须首先选择数据的保存位置,然后才能附加数据。

是否有一种方法可以在不先询问用户将数据库保存到何处的情况下执行此操作?

以下是我的代码:

fun exportDatabase() {
  val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
  intent.type = "*/*" // this line is a must when using ACTION_CREATE_DOCUMENT
  startActivityForResult(
intent,
DATABASE_EXPORT_CODE
  )
 }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  super.onActivityResult(requestCode, resultCode, data)

  when (requestCode) {
DATABASE_EXPORT_CODE -> {
 val userChosenUri = data?.data
 val inStream = getDatabasePath("app_database").inputStream()
 val outStream = userChosenUri?.let { contentResolver.openOutputStream(it) }

 inStream.use { input ->
  outStream.use { output ->
output?.let { input.copyTo(it) }
Toast.makeText(this, "Data exported successfully", Toast.LENGTH_LONG).show()
val emailIntent = Intent(Intent.ACTION_SEND)
//Set type to email
emailIntent.type = "vnd.android.cursor.dir/email"
var toEmail: String = "whatever@gmail.com"
emailIntent.putExtra(Intent.EXTRA_EMAIL, toEmail)
emailIntent.putExtra(Intent.EXTRA_STREAM, userChosenUri)
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Data for Training Log")
startActivity(Intent.createChooser(emailIntent, "Send Email"))
  }
 }

}

else ->
 Log.d("D001", "onActivityResult: unknown request code")
  }

 }

推荐答案

您需要使用FileProvider。但是FileProvider不支持直接传输数据库文件(Check here)。

这可以通过以下方式处理:

解决方案1:

创建支持复制数据库文件的自定义FileProvider类:

class DBFileProvider : FileProvider {
 
 fun getDatabaseURI(c: Context, dbName: String?): Uri? {
  val file: File = c.getDatabasePath(dbName)
  return getFileUri(c, file)
 }

 private fun getFileUri(context: Context, file: File): Uri? {
  return getUriForFile(context, "com.android.example.provider", file)
 }
 
}

并请求清单中的FileProvider

<application>

 ....

 <provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="com.android.example.provider"
  android:exported="false"
  android:enabled="true"
  android:grantUriPermissions="true">
  <meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
 </provider>

</application>

并在resxml下创建provider_paths

<?xml version="1.0" encoding="utf-8"?>

<paths>

 <files-path
  name="databases"
  path="../" />

</paths>

然后通过电子邮件发送此数据库文件:

public static void backupDatabase(AppCompatActivity activity) {
 Uri uri = new DBFileProvider().getDatabaseURI(activity, "app_database.db");
 sendEmail(activity, uri);
}
private fun sendEmail(activity: AppCompatActivity, attachment: Uri) {
 val emailIntent = Intent(Intent.ACTION_SEND)
 //Set type to email
 emailIntent.type = "vnd.android.cursor.dir/email"
 val toEmail = "whatever@gmail.com"
 emailIntent.putExtra(Intent.EXTRA_EMAIL, toEmail)
 emailIntent.putExtra(Intent.EXTRA_STREAM, attachment)
 emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Data for Training Log")
 activity.startActivity(Intent.createChooser(emailIntent, "Send Email"))
}

解决方案2:

将数据库文件复制到临时文件到FileProviderLike支持的目录filesDir

    使用getDatabasePath获取数据库文件

    将数据库文件复制到FileProvider支持的存储目录

    使用FileProvider

    创建新复制文件的URI

fun backupDatabase(activity: AppCompatActivity) {

 // Get the database file
 val dbFile = activity.getDatabasePath("app_database.db")

 try {

  // Copy database file to a temp file in (filesDir)
  val parent = File(activity.filesDir, "databases_temp")
  val file = File(parent, "myDatabase")
  dbFile.copyTo(file)

  // Get Uri of the copied database file from filesDir to be used in email intent
  val uri = getUri(activity.applicationContext, file)

  // Send an email
  sendEmail(activity, uri)

 } catch (e: IOException) {
  e.printStackTrace()
 }
}


private fun getUri(context: Context, file: File): Uri {
 var uri = Uri.fromFile(file)

 // Using FileProvider for API >= 24
 if (Build.VERSION.SDK_INT >= 24) {
  uri = FileProvider.getUriForFile(
context,
"com.android.example.provider", file
  )
 }
 return uri
}

使用与解决方案1相同的清单,并使用创建的临时目录调整resxml下的provider_paths

<?xml version="1.0" encoding="utf-8"?>

<paths>
 <files-path
  name="databases_temp"
  path="/" />
</paths>

nb:在这两个解决方案中,请根据您的需要调整包名称。

好了关于导出房间数据库并附加到Android Kotlin电子邮件的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。

0
没有账号?注册  忘记密码?