场景
从微信打开KML文件,选择自家开发的App打开,发现能够读取读取文件路径,但是在操作的时候显示错误
java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.tencent.mm/MicroMsg/Download/xxx.kml: open failed: EACCES (Permission denied)
|
其中AS工程已经正确配置存储权限,并且application已经配置android:requestLegacyExternalStorage="true"
因项目在Android10上能够正确运行,但是在Android 11及以上有异常,猜想是因为Android 11做了一些限制。
因此采用另外一种方法:先把真实路径从获取到的Uri对象中解析出来,然后把文件拷贝一份到App目录下面,再对这个文件进行解析
public static String getFPUriToPath(Context context, Uri uri) { try { List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS); if (packs != null) { String fileProviderClassName = FileProvider.class.getName(); for (PackageInfo pack : packs) { ProviderInfo[] providers = pack.providers; if (providers != null) { for (ProviderInfo provider : providers) { if (uri.getAuthority().equals(provider.authority)) {
Class<FileProvider> fileProviderClass = FileProvider.class; try { Method getPathStrategy = fileProviderClass.getDeclaredMethod("getPathStrategy", Context.class, String.class); getPathStrategy.setAccessible(true); Object invoke = getPathStrategy.invoke(null, context, uri.getAuthority()); if (invoke != null) { String PathStrategyStringClass = FileProvider.class.getName() + "$PathStrategy"; Class<?> PathStrategy = Class.forName(PathStrategyStringClass); Method getFileForUri = PathStrategy.getDeclaredMethod("getFileForUri", Uri.class); getFileForUri.setAccessible(true); Object invoke1 = getFileForUri.invoke(invoke, uri); if (invoke1 instanceof File) { return ((File) invoke1).getAbsolutePath(); } } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } break;
} } } } } } catch (Exception e) { e.printStackTrace(); } return ""; }
public static String getPathFromInputStreamUri(Context context, Uri uri, String fileName) { InputStream inputStream = null; String filePath = null;
if (uri.getAuthority() != null) { try { inputStream = context.getContentResolver().openInputStream(uri); File file = createTemporalFileFrom(context, inputStream, fileName); filePath = file.getPath();
} catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (Exception e) { e.printStackTrace(); } } }
return filePath; }
private static File createTemporalFileFrom(Context context, InputStream inputStream, String fileName) throws IOException { File targetFile = null;
if (inputStream != null) { int read; byte[] buffer = new byte[8 * 1024]; targetFile = new File(context.getCacheDir(), fileName); if (targetFile.exists()) { targetFile.delete(); } OutputStream outputStream = new FileOutputStream(targetFile);
while ((read = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, read); } outputStream.flush();
try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
return targetFile; }
|