Android 13细分媒体权限弹窗不显示问题求助
Android 13(SDK33)媒体权限请求弹窗不显示问题排查与修复
我已将项目升级至SDK 33,按照谷歌文档将原有的READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限替换为细分媒体权限,但权限请求弹窗始终未出现。以下是我的实现代码:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.storagepermission"> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- Required to maintain app compatibility. --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.StoragePermission" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
MainActivity
class MainActivity : AppCompatActivity() { lateinit var button: Button private val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) @RequiresApi(api = Build.VERSION_CODES.TIRAMISU) private val permissionsFor13 = arrayOf( Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO) fun permissions(): Array<String>? { val p: Array<String> p = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { Log.e("TAG", "permissions: permissionsFor13" ) permissionsFor13 } else { Log.e("TAG", "permissions: permission" ) permissions } return p } @RequiresApi(api = Build.VERSION_CODES.TIRAMISU) private fun arePermissionsEnabled(): Boolean { for (permission in permissions()!!) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) return false } return true } @RequiresApi(api = Build.VERSION_CODES.TIRAMISU) private fun requestMultiplePermissions() { val remainingPermissions = ArrayList<String>() for (permission in permissions()!!) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { remainingPermissions.add(permission) } } } @RequiresApi(33) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button = findViewById(R.id.button) button.setOnClickListener { val readImagePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE if(ContextCompat.checkSelfPermission(this, readImagePermission) == PackageManager.PERMISSION_GRANTED){ Toast.makeText(applicationContext,"permission granted", Toast.LENGTH_LONG).show() arePermissionsEnabled() } else { requestMultiplePermissions() Toast.makeText(applicationContext,"permission Not granted", Toast.LENGTH_LONG).show() } } } }
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"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="311dp" android:text="Button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
问题核心原因
代码中requestMultiplePermissions()方法仅收集了未授权的权限列表,但没有调用系统API发起权限请求,这是弹窗不出现的直接原因。此外还有几处逻辑冗余和注解限制可以优化。
修复后的MainActivity代码
class MainActivity : AppCompatActivity() { lateinit var button: Button // 根据系统版本自动返回对应权限列表 private val requiredPermissions: Array<String> get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { arrayOf( Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO, Manifest.permission.READ_MEDIA_AUDIO ) } else { arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) } // 检查所有必要权限是否已授权 private fun arePermissionsEnabled(): Boolean { return requiredPermissions.all { ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED } } // 发起权限请求 private fun requestMultiplePermissions() { val remainingPermissions = requiredPermissions.filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }.toTypedArray() if (remainingPermissions.isNotEmpty()) { ActivityCompat.requestPermissions( this, remainingPermissions, 100 // 自定义请求码,用于后续处理权限结果 ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button = findViewById(R.id.button) button.setOnClickListener { if (arePermissionsEnabled()) { Toast.makeText(applicationContext, "权限已授权", Toast.LENGTH_LONG).show() } else { requestMultiplePermissions() Toast.makeText(applicationContext, "正在请求权限", Toast.LENGTH_LONG).show() } } } // 可选:处理权限请求结果 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 100) { if (arePermissionsEnabled()) { Toast.makeText(applicationContext, "权限请求成功", Toast.LENGTH_LONG).show() } else { Toast.makeText(applicationContext, "部分权限未授权", Toast.LENGTH_LONG).show() } } } }
额外注意事项
- AndroidManifest.xml的配置是正确的,无需修改
- 测试时需使用Android 13及以上版本的设备/模拟器,低版本会自动适配
READ_EXTERNAL_STORAGE权限 - 若用户之前拒绝权限并勾选"不再询问",需引导用户到应用设置页面手动开启权限
内容的提问来源于stack exchange,提问作者Vinay Bakle
相关产品推荐
相关产品推荐

