【发布时间】:2020-05-24 12:45:07
【问题描述】:
我正在尝试将从图库中选择的图像上传到我的 Springboot 服务器,但是当我的服务尝试发布图像时,我的文件路径权限被拒绝。我已将这些权限添加到我的 AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- permission below just in case, should not be needed I believe -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
然后我实时请求允许选择图像,然后我想将其放置在一个膨胀的视图中,用户可以在其中提供有关图像的更多详细信息,然后将其添加到我稍后将发布的报告中。
由于我遇到了这个权限问题,当我尝试提交这个包含图像 (Uri) 的报告对象时,我也再次请求了权限。
但我仍然收到此错误:
Caused by: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20200206_120434.jpg (Permission denied)
我在谷歌上找到的关于这个错误的每一次点击都会指向一个不要求这个实时许可的人,但我相信我什至做过一次。
这是我的代码的一些相关sn-ps:
else if (view.getId() == R.id.stubNewBreedingReportSelectImageButt) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
} else {
getPhotoFromPhone(); // this starts the intent to pick an image
}
}
}
else if (view.getId() == R.id.stubNewBreedingReportSubmitButt) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
} else {
submitNewBreedingReport();
}
}
}
这是来自我的 onClick(View view) 方法。第一个作品,因为我被允许从画廊中挑选图像。第二个可能不需要根据我发现的从 android 上传图像的项目的每个示例检查权限。
在我的 onActivityResult(int requestCode, int resultCode, Intent data) 方法中,我放大了这个“添加图像详细信息视图”。我还将选定的 Uri 作为私有 Uri selectedImg 存储在活动中以供将来使用。这一切似乎都很好。
然后,当我提交图像时(在 submitNewReport() 方法中),我使用 ExecutorService(java 类)启动一个新的异步线程以进行上传。在这个 Callable 中,我得到了 Springs RestTemplate 的一个实例并尝试发布图像,但是当我的 restTemplate 尝试从我的 Uri 调用并获取文件时,我的权限被拒绝。
这是我的应用程序ImageService中的上传方法:
public Gallery uploadPictureWithInfo(Uri uri, Map<String,Object> imgParams, Context context) {
if (uri.getPath() != null) {
File resourceFile = new File(getPathFromUri(uri,context));
//if (resourceFile.exists()) {
Gallery saved = null;
Map<String,Object> params = new HashMap<>();
params.put(PARAM_FILE, new FileSystemResource(resourceFile));
if (imgParams.get(PARAM_GALLERY_ID) != null || (long) imgParams.get(PARAM_GALLERY_ID) > (long) 0) {
params.put(PARAM_GALLERY_ID, imgParams.get(PARAM_GALLERY_ID));
if (imgParams.get(PARAM_DESCRIPTION) != null) {
params.put(PARAM_DESCRIPTION, imgParams.get(PARAM_DESCRIPTION));
}
if (imgParams.get(PARAM_PHOTOGRAPH) != null) {
params.put(PARAM_PHOTOGRAPH, imgParams.get(PARAM_PHOTOGRAPH));
}
if (imgParams.get(PARAM_USER_ID) != null && (long) imgParams.get(PARAM_USER_ID) > 0) {
params.put(PARAM_USER_ID, imgParams.get(PARAM_USER_ID));
}
HttpEntity requestEntity = new HttpEntity<>(params, AquaDbConfig.getImageHeaders());
ResponseEntity<Gallery> responseEntity =
restTemplate.exchange(AquaDbConfig.getApiUrl() + "/images/uploadImgWithInfo", HttpMethod.POST, requestEntity, Gallery.class);
if (responseEntity.hasBody()) {
saved = responseEntity.getBody();
}
return saved;
}
//}
}
return null;
}
public static String getPathFromUri(Uri uri, Context context) {
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = context.getContentResolver().query(uri,filePath, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
String picturePath = c.getString(columnIndex);
c.close();
return picturePath;
}
我注释掉了对 file.isExist() 的检查以通过该测试,因为否则它不会生成堆栈跟踪。
所以我的问题是当我将图像文件发布到服务器时如何读取它?我阅读了一些关于 FileProvider 类的内容,但在我看来,它用于通过 Intent 将文件发送到新的 Activites 或其他应用程序。在我看来,它似乎不是为此而设计的,因为我从不离开我的 Activity 以在画廊中挑选图像。创建此 ReportedBreeding 对象的不同步骤由膨胀的 ViewStub 处理,而不是新的活动。此外,我使用的 Uri 不是指我为我的应用创建的任何目录,而是指用户图片库(外部存储)。
我还尝试在 android 清单中将我的 ImageService 声明为服务,尽管我不确定我们谈论的是同一种服务。然后我添加了这个权限,但没有区别:
<service
android:name=".service.MyImageFactory"
android:permission="android.permission.READ_EXTERNAL_STORAGE">
</service>
如果您知道如何一直获得此 RestTemplate POST 方法的权限(在我审查的示例中似乎没有其他人需要)或者我如何解决这个问题,请分享!我开始有点沮丧和卡住了。我的问题是为什么 android 需要另一个权限检查,我如何在我的 uploadPictureWithInfo(..) 方法中提供或解决它?
【问题讨论】:
标签: java android android-permissions resttemplate