【发布时间】:2023-10-08 04:15:01
【问题描述】:
我需要帮助解决这个问题,因为我是 Android 新手。
我的应用支持 JellyBean (16) 到 Oreo (26)。
我有一个 UploadService 需要 openInputStream() 上传数据,因为 Nougat 中的新行为。
此代码在 Marshmallow 及以下版本中运行良好,但在 Nougat 上总是给我SecurityException crash。它在使用 error 调用 openInputStream() 的行上崩溃:
java.lang.SecurityException: Permission Denial: 读取 com.miui.gallery.provider.GalleryOpenProvider uri content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FDCIM%2FCamera%2FIMG_20171008_182834。 jpg from pid=30846, uid=10195 需要导出provider,或者grantUriPermission()
文件 uri 可能来自各种应用程序(图库、相机等)。我已将问题范围缩小到来自 ACTION_GET_CONTENT 意图的 uri(任何来自相机意图或 MediaRecorder 的东西都可以正常工作)。
我认为这是因为 uri 在传递到服务时失去了权限,但是添加 Intent.FLAG_GRANT_WRITE_URI_PERMISSION 和 Intent.FLAG_GRANT_READ_URI_PERMISSION 并没有帮助。
还尝试添加 FLAG_GRANT_PERSISTABLE_URI_PERMISSION 标志,但它仍然崩溃,getContentResolver().takePersistableUriPermission() 导致另一个 SecurityException 崩溃,说所述 uri 尚未被授予持久 uri...
UploadService.java
//.......... code to prepare for upload
if ( contentResolver != null && schemeContentFile ) {
mMime = UtilMedia.getMime(this, uri);
try {
InputStream is = contentResolver.openInputStream(uri);
byte[] mBytes = getBytes(is);
Bundle fileDetail = UtilMedia.getFileDetailFromUri(this, uri);
Log.d("AndroidRuntime", TAG + " " + mMime + " " + UtilToString.bundleToString(fileDetail) + " imageFile " + mFile);
currTitle = fileDetail.getString(OpenableColumns.DISPLAY_NAME, "");
MediaType type = MediaType.parse(mMime);
requestFile = RequestBody.create(type, mBytes);
} catch ( IOException e ) {
e.printStackTrace();
} catch ( SecurityException e ) {
e.printStackTrace();
}
}
//............continue to upload
提前谢谢你。
编辑(附加信息)
如果这很重要。调用服务的活动在将所有必需的数据发送到服务后调用finish(),让用户使用应用程序,同时在后台恢复上传(通知用户)。而且,上传是基于队列的,用户可以在活动中选择上传多个文件。第一个文件总是被上传,但之后的文件总是返回崩溃。
【问题讨论】:
-
某些设备不允许从相机或图片目录读取文件的权限。如果从其他目录上传文件是否存在问题?
-
感谢您的建议!我现在没有 Nougat 设备,但我会在有的时候尝试一下。哦,我可以得到mime就好了(该函数还使用了ContentResolver和相同的uri),是否意味着当时启用了读/写uri权限,但不知何故它需要其他权限才能直接读取文件?跨度>
-
所以,我尝试了你的建议@NabinBhandari,但它仍然给了我同样的例外。我还编辑了我的帖子以添加更多信息以防万一。
-
小米设备有这个问题。我不明白为什么从 Uri 读取的权限不像其他画廊提供者那样持久。就我而言,我试图从实际收到 Uri 的活动开始的活动中打开 Uri。使用标准的 Android 提供程序,它可以工作。 @NabinBhandari 有没有办法获得可以通过 GET_CONTENT 请求传播的权限?还是应该切换到 OPEN_DOCUMENT?根据文档
Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to documents owned by a document provider
标签: android permission-denied android-7.0-nougat securityexception