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

Android 14中申请READ_MEDIA_VISUAL_USER_SELECTED后PhotoPicker仍显示全量媒体

Android 14 READ_MEDIA_VISUAL_USER_SELECTED权限与PhotoPicker适配问题

问题背景

Android 14新增了READ_MEDIA_VISUAL_USER_SELECTED权限,该权限可提供对用户照片和视频的部分临时访问权限,权限申请弹窗包含「选择照片和视频」「允许全部」「不允许」三个选项。官方文档提到,若应用已使用PhotoPicker则无需额外操作适配该权限,但测试时遇到如下问题:

测试步骤

  • 申请READ_MEDIA_IMAGES和READ_MEDIA_VISUAL_USER_SELECTED权限;
  • 在权限弹窗中选择「选择照片和视频」,选中少量照片后点击允许;
  • 打开PhotoPicker时,发现其仍显示设备中的全部媒体内容,而非仅用户授权的媒体。

代码实现

Case 1 使用Intent实现

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    Button takePictureButton;
    int RESULT_CODE = 0;
    int REQUEST_CODE = 1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.img);
        takePictureButton = findViewById(R.id.btn_take_picture);

        takePictureButton.setOnClickListener(view -> {
            if (android.os.Build.VERSION.SDK_INT == 34) {
                int result14 = this.checkSelfPermission(READ_MEDIA_VISUAL_USER_SELECTED);
                boolean hasReadMediaPermissionAndroid14 = PackageManager.PERMISSION_GRANTED == result14;

                if (hasReadMediaPermissionAndroid14) {
                    Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
                    intent.setType("image/*");
                    startActivityForResult(intent, RESULT_CODE);
                } else {
                    requestPermissions(new String[] {READ_MEDIA_IMAGES, READ_MEDIA_VISUAL_USER_SELECTED}, REQUEST_CODE);
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data != null) {
            imageView.setImageURI(data.getData());
        }
    }
}

Case 2 遵循官方PhotoPicker文档实现

public class MainActivity extends AppCompatActivity {
    ImageView imageView;
    Button takePictureButton;
    int REQUEST_CODE = 1;

    ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
            registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), uri -> {
                if (uri != null) {
                    imageView.setImageURI(uri);
                    Log.d("PhotoPicker", "Selected URI: " + uri);
                } else {
                    Log.d("PhotoPicker", "No media selected");
                }
            });
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.img);
        takePictureButton = findViewById(R.id.btn_take_picture);

        takePictureButton.setOnClickListener(view -> {
                    if (android.os.Build.VERSION.SDK_INT == 34) {
                        int result14 = this.checkSelfPermission(READ_MEDIA_VISUAL_USER_SELECTED);
                        boolean hasReadMediaPermissionAndroid14 = PackageManager.PERMISSION_GRANTED == result14;

                        if (hasReadMediaPermissionAndroid14) {
                            pickMedia.launch(new PickVisualMediaRequest.Builder()
                                    .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE)
                                    .build());
                        } else {
                            requestPermissions(new String[]{READ_MEDIA_IMAGES, READ_MEDIA_VISUAL_USER_SELECTED}, REQUEST_CODE);
                        }
                    }
                }
        );
    }
}

AndroidManifest.xml配置

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintVertical_bias="0"
        android:src="@drawable/img"
        tools:ignore="ContentDescription" />

    <Button
        android:id="@+id/btn_take_picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="take picture"
        app:layout_constraintTop_toBottomOf="@id/img"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="20dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

问题现象

选择「选择照片和视频」并授权部分照片后,打开PhotoPicker仍展示设备内全部媒体内容,未过滤到仅授权的媒体。

疑问

请问是我对权限机制理解有误,还是代码存在问题?该权限的实际预期行为是什么?我应如何处理此问题?


内容的提问来源于stack exchange,提问作者Khuê Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:43:10