You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:32:39