当我试图打开一个文件时,应用程序崩溃了。它可以在Android Nougat下运行,但在Android Nougat上它会崩溃。只有当我试图从SD卡,而不是从系统分区打开文件时,它才会崩溃。权限问题?
示例代码:
File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line
日志:
android.os.FileUriExposedException:
///storage/emulated/0/test.txt
Intent.getData ()
编辑:
当针对Android Nougat时,file:// uri不再被允许。我们应该使用content:// uri。但是,我的应用程序需要打开根目录下的文件。什么好主意吗?
我不知道为什么,我所做的一切与Pkosta (https://stackoverflow.com/a/38858040)完全相同,但一直得到错误:
Permission Denial:从ProcessRecord{reacted} (reacted)打开提供者,而不是从uid reacted导出
我在这个问题上浪费了好几个小时。罪魁祸首吗?芬兰湾的科特林。
val playIntent = Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent实际上是设置getIntent()。addFlags而不是在我新声明的playIntent上操作。
我知道这是一个相当老的问题,但这个答案是给未来的观众的。所以我遇到过类似的问题,经过研究,我找到了这种方法的替代方案。
你的意图
从Kotlin中的路径查看您的图像
val intent = Intent()
intent.setAction(Intent.ACTION_VIEW)
val file = File(currentUri)
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val contentURI = getContentUri(context!!, file.absolutePath)
intent.setDataAndType(contentURI,"image/*")
startActivity(intent)
主要功能如下
private fun getContentUri(context:Context, absPath:String):Uri? {
val cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf<String>(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=? ",
arrayOf<String>(absPath), null)
if (cursor != null && cursor.moveToFirst())
{
val id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID))
return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(id))
}
else if (!absPath.isEmpty())
{
val values = ContentValues()
values.put(MediaStore.Images.Media.DATA, absPath)
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
else
{
return null
}
}
同样地,除了图像,你可以使用任何其他文件格式,比如pdf,在我的例子中,它工作得很好
我的答案是“乌里”。解析文件路径为字符串,而不是使用Uri.fromFile()。
String storage = Environment.getExternalStorageDirectory().toString() + "/test.txt";
File file = new File(storage);
Uri uri;
if (Build.VERSION.SDK_INT < 24) {
uri = Uri.fromFile(file);
} else {
uri = Uri.parse(file.getPath()); // My work-around for SDKs up to 29.
}
Intent viewFile = new Intent(Intent.ACTION_VIEW);
viewFile.setDataAndType(uri, "text/plain");
startActivity(viewFile);
似乎fromFile()使用了一个文件指针,当内存地址暴露给所有应用程序时,我认为这可能是不安全的。但是文件路径字符串不会伤害任何人,所以它不会抛出FileUriExposedException异常。
测试API等级9至29!在另一个应用程序中成功打开文本文件进行编辑。不需要FileProvider,也不需要Android支持库。这将不能在API级别30(Android 11)或更新版本上正常工作,因为getExternalStorageDirectory()已弃用。