Android 11及以上与低版本设备图库选图问题解决
问题根源
你的代码在Android 10及以上版本失效,核心原因有两点:
- Android 10(API 29)开始实行分区存储,
READ_EXTERNAL_STORAGE权限的作用范围大幅缩小,且你在权限配置中添加了maxSdkVersion="29",导致API 30+的设备根本不会加载该权限。 - 代码未区分系统版本,统一检查
READ_EXTERNAL_STORAGE权限,Android 10+设备因无此权限,会一直卡在权限申请环节,无法触发选图逻辑。
修复步骤
1. 修正权限配置
移除READ_EXTERNAL_STORAGE的版本限制,同时适配Android 13+的细分媒体权限(若项目targetSdkVersion ≥33):
<!-- 适配Android 9及以下的存储权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13+ 需单独申请图片权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33" />
2. 修改权限判断逻辑
根据系统版本区分需申请的权限,Android 10-12可直接跳过权限检查(使用ACTION_PICK选图无需存储权限):
layoutMiscellaneous.findViewById(R.id.laoutAddImage).setOnClickListener(view -> { bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); String[] requiredPermissions; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // Android 13及以上,使用新的图片权限 requiredPermissions = new String[]{Manifest.permission.READ_MEDIA_IMAGES}; } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // Android 10-12,直接触发选图,无需权限 selectImage(); return; } else { // Android 9及以下,使用旧存储权限 requiredPermissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}; } // 检查权限状态,未授权则申请,已授权则选图 if (ContextCompat.checkSelfPermission(getApplicationContext(), requiredPermissions[0]) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(CreateNoteActivity.this, requiredPermissions, REQUEST_CODE_STORAGE_PERMISSION); } else { selectImage(); } });
3. 保留原选图方法
ACTION_PICK是系统标准选图接口,全版本兼容,无需修改:
private void selectImage() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_CODE_SELECTED_IMAGE); } }
4. 权限回调逻辑复用
原回调逻辑无需大幅调整,可兼容新旧权限的授权结果判断:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_STORAGE_PERMISSION && grantResults.length > 0) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { selectImage(); } else { Toast.makeText(this, R.string.permissao_recusada, Toast.LENGTH_SHORT).show(); } } }
关键说明
- Android 10及以上版本,使用
ACTION_PICK从系统相册选图时,系统会自动授予App临时访问选中图片的权限,无需申请存储权限。 - Android 13将原存储权限拆分为图片、视频、音频三个细分权限,需单独申请对应媒体类型的权限。
内容的提问来源于stack exchange,提问作者Ezequiel Guazai
相关产品推荐
相关产品推荐

