图片的URI不断变化,这是模拟器问题还是我做错了什么?

Uri of images keeps changing, is this an emulator issue or am I doing something wrong?

我已经设置了一些代码来从图库中挑选图片。

private void setImg() {
        Intent imgIntent = new Intent(Intent.ACTION_PICK);
        imgIntent.setType("image/*");
        startActivityForResult(imgIntent, IMG_INPUT);
    }

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == IMG_INPUT) {
                Uri imgUri = data.getData();
                if (imgUri != null) {
                    imgStrUri = imgUri.toString();
                    recipeImg.setImageURI(imgUri);
                    recipeImg.setVisibility(View.VISIBLE);
                    imgBtn.setText(getString(R.string.remove_image));
                } else {
                    Toast.makeText(this, "Something went wrong",Toast.LENGTH_LONG).show();
                }
            }
        }
    }

图像的Uri然后作为字符串存储在自定义数据结构中(以imgStrUri的形式)并使用gson保存到sharedprefs。

稍后当我从 sharedpref 加载数据以在另一个 activity 中设置图像时,存储的 Uri 不再有效并且没有图像被放入我的图像视图中。

String image = recipeCard.getRecipeImage();
        if (image != null) {
            ((ImageView) findViewById(R.id.image_display)).setImageURI(Uri.parse(image));
        }

我做了一些调试,发现虽然 Uri 被保存到我的数据结构中(recipeCard 是一个实例)它不再指向任何东西,因为我的 ImageView 中没有加载任何东西。所以我又去 运行 我的 setImg 功能,选择了同一张图片才发现图片现在有一个稍微不同的 Uri。所以我的问题是,这是模拟器问题还是我做错了什么?

以下是 Uri 如何更改的示例:

content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F11/ORIGINAL/NONE/1007823737

content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F11/ORIGINAL/NONE/1302460634

如您所见,最后一个斜线更改后的数字。

没有在这里发布很多问题,所以不太习惯这样表述我的问题。因此,我很可能忘记提供一些需要的信息或代码片段,如果是这样,请告诉我,我会马上处理。

I have set up some code to pick an image from the gallery

ACTION_PICK 不采用 MIME 类型。

The Uri of the image is then stored in a custom datastructure as a String (in the form of imgStrUri) and saved to sharedprefs using gson.

这不适用于 ACTION_PICK。您访问 Uri is going to be limited 标识的内容的权利。引用我自己的博客 post:

If you need durable access — such as being able to access the content tomorrow — you have two main options that I know of:

  1. If you used ACTION_OPEN_DOCUMENT, ACTION_CREATE_DOCUMENT, or similar Storage Access Framework actions, you can try using takePersistableUriPermissions() on ContentResolver to get long-term access to the content.
  1. Otherwise, before your component is destroyed, make a local copy of the content in your app's portion of internal storage (e.g., getCacheDir()). This approach sucks, as it duplicates the content, and changes to the original edition of the content will not be reflected in the copy. Use appropriate UI terms (e.g., "import") to help the user understand that this is what is going on.

不要假设您的 ACTION_PICK Uri 稍后可以使用,请从您的 JSON.

中读回

So I went to run my setImg function again and chose the same picture only to find that the picture now had a slightly different Uri.

FWIW,不要求任何 ACTION_PICK 实现与 return 一致的 Uri 值。您会在其他地方看到这种行为,例如您可以通过多个 URL 访问此网页。