如何共享应用的Room数据库?导出SQLite文件分享失败求助
解决内部SQLite数据库分享失败的问题
你遇到的问题核心是内部存储的文件无法直接通过file:// Uri分享给其他应用——其他应用没有访问你应用私有目录的权限,而且Android 7.0+还会禁止跨应用传递file:// Uri(即使你没触发异常,低版本下其他应用也读不到文件)。
以下是完整的解决步骤:
1. 配置FileProvider
在AndroidManifest.xml的<application>标签内添加FileProvider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
authorities使用你的应用ID加上后缀,确保唯一exported必须设为false,这是FileProvider的安全要求grantUriPermissions设为true,允许临时授权其他应用访问文件
2. 创建文件路径配置文件
在res/xml目录下创建file_paths.xml(没有xml目录就新建),添加以下内容:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 匹配应用默认数据库目录下的所有文件 --> <database-path name="app_databases" path="." /> </paths>
<database-path>专门用于指向应用的默认数据库目录,path="."表示共享整个数据库目录。
3. 修改分享代码
替换原来的shareData()方法,用FileProvider生成安全的content:// Uri,并添加临时读取权限:
private fun shareData() { val dbFile = application.getDatabasePath(LOCAL_DB_NAME) if (!dbFile.exists()) { // 处理数据库文件不存在的情况,比如弹提示 return } try { // 生成content://格式的Uri,authorities要和Manifest里的配置一致 val contentUri = FileProvider.getUriForFile( application, "${application.packageName}.fileprovider", dbFile ) val shareIntent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_STREAM, contentUri) type = "application/x-sqlite3" // 给接收应用临时授予文件读取权限 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } startActivity(Intent.createChooser(shareIntent, "Share Data")) } catch (e: Exception) { e.printStackTrace() } }
关键修改说明:
- 直接使用
File对象而非路径字符串,避免Uri解析错误 - 通过
FileProvider.getUriForFile()生成content://开头的安全Uri,替代原来的file://Uri - 添加
Intent.FLAG_GRANT_READ_URI_PERMISSION,让接收应用临时获得文件读取权限 - 确保
authorities参数和Manifest中配置的完全一致
内容的提问来源于stack exchange,提问作者YeO
相关产品推荐
相关产品推荐

