问题描述
我有两个版本的应用程序共有的文件访问例程(这是完整的方法):
public void openDataRestore(CfgTab tableFileEnum){
cfgStatFileName = sensorCalibFileNames[tableFileEnum.ordinal()]+".cfg"; // "FrAccTab.cfg"
File apdatSubDir;
if(System.getenv("EXTERNAL_STORAGE")!=null){
try {
String extPath;
extPath = System.getenv("EXTERNAL_STORAGE"); // "/sdcard"
String fullPathName = extPath+getApplicationContext().getString(R.string.dat_dir); // "/sdcard/apdat/"
apdatSubDir = new File(fullPathName);
File[] reportFiles = apdatSubDir.listFiles(new FilenameFilter() {
public boolean accept(File dir,String name) {
return name.matches(cfgStatFileName); // "FrAccTab.cfg"
}
});
if(reportFiles!=null&&reportFiles.length==1) {
File reportFile = reportFiles[0];
cfgFr = new FileReader(reportFile);
cfgIn = new BufferedReader(cfgFr);
}
} catch (IOException ioe) {
if(ioe.getMessage().contains("Permission denied")){
AlertDialog.Builder builder2 = new AlertDialog.Builder(activeFragmentView.getContext());
builder2.setMessage(ioe.getMessage()+"\n\n"+getApplicationContext().getString(R.string.store_perms))
.setNeutralButton(R.string.ok,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
confirmOpenRestoreFile = true;
}
});
builder2.show();
return;
}
System.err.println(ioe.getMessage());
}
}
}
在较早的部署中,它可与清单权限API 29:目标27:
一起使用<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
但是在较新的一种API 30 Target 30上,只有在这样修改清单的情况下,它才有效:
<application
android:requestLegacyExternalStorage="true"
....
</application>
我的测试设备是Android 10,这意味着API 29,这意味着使用AS4.0推荐的API 30目标30会给代码段带来更多麻烦?我尝试过的另一种文件访问过程:
File targetItem = new File(fullPathName+cfgStatFileName);
if(targetItem!=null){
cfgFr = new FileReader(targetItem);
cfgIn = new BufferedReader(cfgFr);
}
在创建新的FileReader(targetItem)时在API 30 Target 30中生成IOException,并且比尝试先打开子目录的失败失败更令人欣慰。 而且,File.mkdirs()在只读上下文中似乎不合适,这是较新的应用程序试图从较旧的应用程序读取的内容。理想情况下,需要两者在特定平台上共存吗?。
PS:我删除了多余的mkdirs(),还尝试通过撤消Manifest requestLegacyExternalStorage来重新创建错误。但是问题并未重现,因为显然Android 10现在知道此新版本已获得许可。所以问题出在新应用上,因为旧应用在Android从9升级到10之前已经获得许可...
解决方法
似乎与新应用的Android 10权限处理有关。在出现问题期间,没有任何手动的“ Android设置权限管理器允许”尝试将允许新应用在允许的“ 14 of 26”存储权限下列出,现在,由于在运行带有requestLegacyExternalStorage =“ true”的操作后,Android 10现在显示“允许26个中的15个,并且该应用现在已列出,而在此之前,我必须先按名称搜索它,以手动设置其权限。