由于我是Android新手,所以需要您的帮助解决这个问题。
我的应用程序支持JellyBean (16)到Oreo (26)。
我有一个UploadService,因为Nougat中的新行为,需要openInputStream()
上传数据。
这段代码在Marshmallow及以下版本中运行良好,但在Nougat上总是给我SecurityException
崩溃,并在调用openInputStream()
的那一行崩溃,出现错误:
java.lang.SecurityException: Permission Denial: reading 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 requires the provider be exported, or 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()
,让用户使用应用程序,而上传在后台恢复(通过通知告诉用户)。此外,上传基于队列,并且用户可以选择在活动中上传多个文件。第一个文件总是会被上传,但之后的文件总是崩溃返回。