解决PhotoPicker临时Uri重启失效问题:保存图片至应用目录
问题:PhotoPicker临时Uri持久化访问问题
我在SQLite数据库中存储图片路径,使用PhotoPicker获取图片后通过setImageURI()显示,将Uri存入ImageView的Tag再保存到数据库。当前会话内能正常读取Uri显示图片,但PhotoPicker返回的临时Uri(例如content://media/picker/0/com.android.providers.media.photopicker/media/1000000033)在重启应用后会抛出java.lang.SecurityException: Calling uid ( 10190 ) does not have permission to access picker uri错误。
疑问
- 如何实现Uri的持久化访问?
- 是否需要将图片复制到应用可永久访问的目录(需包含权限说明及代码)?
- 能否直接永久访问该Uri?
- 有无更优方案?
初始代码
启动PhotoPicker的代码
private static void pickImage() { Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES); resultLauncher.launch(intent); }
处理选择结果的代码
private void registerResult() { resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult o) { try { Uri imageUri = o.getData().getData(); imageView.setImageURI(imageUri); imageView.setTag(imageUri); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getContext(), "Error!", Toast.LENGTH_SHORT).show(); } } }); }
从数据库读取Uri并显示的代码
stringUri = cursor.getString(5); Uri imageUri = Uri.parse(stringUri); alertBuilderPflanzeBild.setImageURI(imageUri); alertBuilderPflanzeBild.setTag(imageUri);
我的解决方案
保存图片到应用目录的代码
private static String savePic (ImageView imageView, String subfolder, String pictureName) { // subfolder: Pflanzen, Rezepte, .. BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); Bitmap bitmap = drawable.getBitmap(); try { File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+"/Pictures/[APP_NAME]/"+subfolder+"/",pictureName+".jpg"); if (!file.exists()) { Log.d(TAG, "Folder '" + file.toString() + "' doesn't exist, creating it..."); boolean rv = Objects.requireNonNull(file.getParentFile()).mkdir(); Log.d(TAG, "Folder creation " + ( rv ? "success" : "failed")); } else { Log.d(TAG, "Folder already exists."); } FileOutputStream out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); out.flush(); out.close(); return file.getAbsolutePath(); } catch (Exception ex) { ex.printStackTrace(); } return null; }
从本地路径读取图片的代码
private static Bitmap getPic (String path) { File file = new File(path); Bitmap bmap=BitmapFactory.decodeFile(file.getAbsolutePath()); //imageView.setImageBitmap(bmap); return bmap; }
结论
先通过临时Uri加载图片到ImageView,再调用savePic()将图片保存到应用专属目录,把返回的绝对路径存入数据库;后续通过getPic()从路径读取图片,实现持久化访问。
内容的提问来源于stack exchange,提问作者timmy
相关产品推荐
相关产品推荐

