大家好!)我是Android开发的新手,现在正在尝试为Android制作文件管理器 .
我遇到了这个问题,当我尝试使用设备上安装的其他应用程序实现打开文件时,可以使用此文件 .
简要背景故事:
在Android N推出之前,我已经使用这段代码打开文件
//intent to navigate file;
i.setDataAndType(Uri.parse("file://" + destinationPath), ext);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Verify that the intent will resolve to an activity
try {
if (i.resolveActivity(activity.getPackageManager()) != null) {
//start this activity
activity.startActivity(i);
} else {
Toast.makeText(activity.getBaseContext(), R.string.browse_to_file_error_toast_1, Toast.LENGTH_LONG).show();
}
} catch (java.lang.Exception e) {
Toast.makeText(activity.getBaseContext(), R.string.browse_to_file_error_toast_2, Toast.LENGTH_LONG).show();
}
但是在Android N发布新规则后应用于Intents . 现在我们不能只将Uri附加到Intent . 如果我们的应用程序中的"targetSdkVersion"参数设置为24或更高,我们将在Android N设备上出现此错误android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()
Google完成了部分访问应用程序流程文件的访问权限,该文件由我们的应用程序启动以打开文件 . https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en
所以,我重构了代码,如下所示:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
i.setDataAndType(FileProvider.getUriForFile(activity.getBaseContext(), BuildConfig.APPLICATION_ID + ".provider", destinationPath), ext);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Verify that the intent will resolve to an activity
try {
if (i.resolveActivity(activity.getPackageManager()) != null) {
//start this activity
activity.startActivity(i);
} else {
Toast.makeText(activity.getBaseContext(), R.string.browse_to_file_error_toast_1, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(activity.getBaseContext(), R.string.browse_to_file_error_toast_2, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
我想,我摆脱了这个问题 . 不幸的是,我错了 . 新的代码片段仅适用于“/ storage / emulated / 0”目录中的文件(或任何路径,由Environment.getExternalStorageDirectory()方法返回) . 当我试图在外部存储器上打开文件时,例如USB闪存驱动器或设备上的SD卡(那些具有大量内置内存的设备),这段代码与FileProvider不起作用!
java.lang.IllegalArgumentException:无法在android.support的android.support.v4.content.FileProvider $ SimplePathStrategy.getUriForFile(FileProvider.java:711)中找到包含/storage/1AF0-391B/myNewFile.txt的已配置根目录 . v4.content.FileProvider.getUriForFile(FileProvider.java:400)
我发现了,为什么会发生这种错误 . 简单地说,FileProvider只能处理"/storage/emulated/0"目录中的文件 . (因此,FileProvider仅用于内部存储!)https://developer.android.com/reference/android/support/v4/content/FileProvider.html#ProviderDefinition(参见"Specifying Available Files"部分)
My question: How to deal with this bad thing? Is there any APIs, that file managers with "targetSdkVersion = 24" can use to open files on Android Nougat devices (not only on Internal storage, but also on SD cards and USB flash drives as well)?
我不想将“targetSdkVersion”参数设置为23.它“解决”了这个问题并允许我将“文件”Uri附加到Intents并且不使用任何提供者 . 但是,当Android的新版本推出时,我想让我的应用程序保持最新状态 .
谢谢你的建议!
如果我犯了错误,抱歉我的英语 .