解决Android PDFView重启后权限失效问题

解决Android PDFView重启后权限失效问题

本文将深入探讨android应用中使用PDFView库打开PDF文件时,设备重启后出现SecurityException权限错误的问题,并提供详细的解决方案。主要原因是URI权限在重启后丢失,导致应用无法再次访问已选择的PDF文件。通过使用takePersistableUriPermissions()方法获取持久化URI权限,可以确保应用在重启后仍然能够访问PDF文件,从而避免权限问题。

当你在Android应用中使用barteksc/AndroidPdfViewer库打开PDF文件时,可能会遇到一个问题:当设备重启后,应用再次尝试打开之前保存的PDF文件URI时,会抛出SecurityException,提示缺少MANAGE_DOCUMENTS权限。这是因为通过ACTION_OPEN_DOCUMENT获取的URI权限在应用重启后会失效。

解决这个问题,需要利用ContentResolver的takePersistableUriPermissions()方法来获取持久化的URI权限。以下是详细的步骤和代码示例:

1. 移除不必要的Flag

首先,在启动ACTION_OPEN_DOCUMENT Intent时,移除FLAG_GRANT_PERSISTABLE_URI_PERMISSION Flag,因为我们将在onActivityResult()中手动处理持久化权限。

intent = new Intent(); if (Build.VERSION.SDK_INT < 19){     intent.setAction(Intent.ACTION_GET_CONTENT); } else {     intent.setAction(Intent.ACTION_OPEN_DOCUMENT);     intent.addCategory(Intent.CATEGORY_OPENABLE);     //intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); // 移除此行 }  intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |  Intent.FLAG_GRANT_WRITE_URI_PERMISSION  ); intent.setType("application/pdf");

2. 在onActivityResult()中获取持久化URI权限

在onActivityResult()方法中,当接收到ACTION_OPEN_DOCUMENT的结果时,调用takePersistableUriPermissions()方法。

@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent resultData) {     super.onActivityResult(requestCode, resultCode, resultData);     if (requestCode == 1002 && resultCode == Activity.RESULT_OK) {         Uri uri;          if (resultData != null) {             uri = resultData.getData();             String name = getFileName(uri);              // 获取持久化URI权限             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                 final int takeFlags = resultData.getFlags()                         & (Intent.FLAG_GRANT_READ_URI_PERMISSION                         | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);                 ContentResolver resolver = getContentResolver();                 resolver.takePersistableUriPermission(uri, takeFlags);             }              db.insertRowAdmins(name, uri.toString(), R.drawable.book, 23, db.getNameTableId().get(positionTab));             setNotify();         }     } }

代码解释:

  • resultData.getFlags(): 获取 Intent 携带的 Flags。
  • & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION): 提取出读写权限相关的 Flag。
  • getContentResolver(): 获取 ContentResolver 实例。
  • resolver.takePersistableUriPermission(uri, takeFlags): 关键步骤,请求系统授予应用对该 URI 的持久化读写权限。

3. 权限声明(AndroidManifest.xml

虽然MANAGE_DOCUMENTS权限看起来相关,但实际上,对于通过ACTION_OPEN_DOCUMENT获取的URI,并不需要此权限。确保你的Manifest文件中包含以下权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果你的应用需要写入PDF文件,还需要:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

4. 注意事项

  • 确保你的应用在处理URI时,始终检查URI的有效性。
  • 如果用户删除了文件,即使有持久化URI权限,也无法访问该文件。
  • 在保存URI到数据库之前,确保已经获取了持久化权限。

总结

通过移除不必要的Flag,并在onActivityResult()中使用takePersistableUriPermissions()方法,可以解决Android应用重启后PDFView库打开PDF文件时出现的SecurityException权限问题。 这种方法允许你的应用程序在重启后仍然能够访问用户选择的PDF文件,提供更好的用户体验。 记住,在处理文件URI时,始终要小心处理权限问题,并确保你的应用能够正确处理文件不存在的情况。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享