如何用指定应用打开Android Assets目录下的文件?
问题原因
file:///android_asset/ 是当前应用APK内部资产目录的URI,属于应用沙箱内的私有资源,其他应用(比如这里的Nova Launcher)没有权限直接访问这个路径,所以调用startActivity后无响应。另外你申请的读写权限仅针对外部存储,对APK内部的Assets目录完全无效。
解决方案
要让其他应用能访问Assets里的文件,得先把文件复制到其他应用可访问的位置,再通过合法的共享URI传递给目标应用。具体步骤如下:
1. 把Assets文件复制到可共享目录
优先选择应用的私有外部存储目录(Android 4.4+无需额外权限),也可以选外部公共存储(需要读写权限)。这里以私有外部存储为例:
private File copyAssetToExternal(String assetPath, String fileName) throws IOException { // 获取应用私有外部存储的files目录,其他应用可通过FileProvider访问 File externalDir = getExternalFilesDir(null); File outputFile = new File(externalDir, fileName); if (outputFile.exists()) { return outputFile; // 已存在直接返回,不用重复复制 } // 从Assets读取文件并写入外部目录 InputStream inputStream = getAssets().open(assetPath); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } inputStream.close(); outputStream.close(); return outputFile; }
2. 用FileProvider生成合法的共享URI
Android 7.0及以上禁止直接用file:// URI给其他应用传文件,必须用FileProvider生成content://类型的URI:
第一步:在AndroidManifest.xml里注册FileProvider
<application> ... <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> </application>
第二步:创建res/xml/file_paths.xml文件
定义FileProvider允许访问的目录,对应刚才的私有外部存储:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="external_files" path="." /> </paths>
3. 调整Intent调用代码
复制完文件后,用共享URI启动Nova Launcher:
try { // 复制Assets里的目标文件到外部目录 File backupFile = copyAssetToExternal("extensions/file.novabackup", "file.novabackup"); // 生成FileProvider的共享URI Uri fileUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", backupFile); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(fileUri, "application/octet-stream"); // 给Nova Launcher临时授予文件读取权限 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setPackage("com.teslacoilsw.launcher"); // 先判断是否有能处理这个Intent的Activity,避免崩溃 if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { // 这里可以加个提示,比如"未安装Nova Launcher或应用不支持该操作" } } catch (IOException e) { e.printStackTrace(); // 处理文件复制失败的情况,比如提示用户"文件读取失败" }
额外补充
如果Nova Launcher不支持content:// URI,可以试试把文件复制到外部公共存储(比如Environment.getExternalStorageDirectory()),但要注意:
- 需在AndroidManifest中声明
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限 - Android 6.0+要动态申请权限
内容的提问来源于stack exchange,提问作者AceDasXan
相关产品推荐
相关产品推荐

