因 Android 10 即以上 读取 内部存储 的file 会报错:open failed: EACCES (Permission denied),所以只能 根据uri 生成新的 file。
ps:虽然在AndroidManifest.xml中的application结点里添加属性配置:android:requestLegacyExternalStorage="true"来请求使用旧的存储模式,就可以根据uri获取path 进而获取file,这样就解决了报:open failed: EACCES (Permission denied),但以后Android版本会对该配置失效,所以该方法不建议!!
详细代码如下:
public static File getFile(Context context,Uri uri){
File file=null;
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.Q){
//根据uri 生成新的 file
file=createFile(context,uri);
}else {
//Android 10 以下
//根据 uri 读取 其所在的file
file=new File(getPath(context,uri));
}
return file;
}
/**====根据 uri(content或file开头都行)生成新的file
* */
public static File createFile(Context context,Uri uri) {
//https://www.jb51.net/article/181745.htm
//文件夹 这两种文件夹都会随软件卸载而删掉
File folder = context.getExternalCacheDir();//在Android>data>包名>的cache目录下,一般存放临时缓存数据
//File folder = this.getExternalFilesDir("image");//在Android>data>包名>的files的image目录下,一般放一些长时间保存的数据
if (!folder.exists()){
folder.mkdir();
}
//file图片
File file=new File(folder.getAbsolutePath()+File.separator+"newFile.jpg");
try {
//根据uri获取输入字节流
InputStream inputStream = context.getContentResolver().openInputStream(uri);
//==把输入流写进file里
FileOutputStream fileOutputStream=new FileOutputStream(file);
byte[] buffer=new byte[1024];
int byteRead;
while (-1 != (byteRead=inputStream.read(buffer))){
fileOutputStream.write(buffer,0,byteRead);
}
fileOutputStream.flush();
inputStream.close();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}