本文介绍了导出房间数据库并附加到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" 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" 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
使用与解决方案1相同的清单,并使用创建的临时目录调整resxml下的provider_paths:
<?xml version="1.0" encoding="utf-8"?> <paths> <files-path name="databases_temp" path="/" /> </paths>nb:在这两个解决方案中,请根据您的需要调整包名称。
更多推荐
导出房间数据库并附加到Android Kotlin电子邮件
发布评论