Android13+ WebView媒体权限弹窗不显示问题适配指导
Android 13 WebView媒体权限弹窗不显示的解决方案
核心问题原因
Android 13(API 33)起,原有的READ_EXTERNAL_STORAGE权限被拆分成READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO三个细分权限,这些权限属于危险权限,仅在Manifest中声明是不够的,必须在代码中动态申请才会触发权限弹窗。
必须修改MainActivity的代码,具体步骤如下:
1. 定义权限常量与请求码
在MainActivity类中添加以下常量:
private static final int REQUEST_MEDIA_PERMISSIONS = 100; // 根据需求选择要申请的权限,示例为图片+视频权限 private String[] ANDROID_13_MEDIA_PERMISSIONS = { Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO };
2. 在页面初始化时检查并申请权限
修改onCreate方法,根据系统版本判断要申请的权限:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { // 检查Android 13+的媒体权限 boolean hasImagePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED; boolean hasVideoPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED; if (!hasImagePerm || !hasVideoPerm) { ActivityCompat.requestPermissions(this, ANDROID_13_MEDIA_PERMISSIONS, REQUEST_MEDIA_PERMISSIONS); } else { initWebView(); } } else { // Android 12及以下使用旧存储权限(兼容原有逻辑) String[] OLD_STORAGE_PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE}; if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, OLD_STORAGE_PERMISSIONS, REQUEST_MEDIA_PERMISSIONS); } else { initWebView(); } } }
3. 处理权限申请结果回调
重写onRequestPermissionsResult方法,根据用户授权结果处理后续逻辑:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_MEDIA_PERMISSIONS) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { initWebView(); } else { Toast.makeText(this, "需要授予媒体权限才能使用上传功能", Toast.LENGTH_SHORT).show(); } } }
4. 抽离WebView初始化逻辑
把原来的WebView配置代码放到单独的initWebView方法中,确保只有权限授予后才初始化WebView:
private void initWebView() { WebView webView = findViewById(R.id.webview); WebSettings webSettings = webView.getSettings(); // 基础配置 webSettings.setJavaScriptEnabled(true); webSettings.setAllowFileAccess(true); webSettings.setAllowContentAccess(true); // 关键:处理WebView文件上传,必须设置WebChromeClient的onShowFileChooser webView.setWebChromeClient(new WebChromeClient() { @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { Intent intent = fileChooserParams.createIntent(); try { startActivityForResult(intent, 101); } catch (ActivityNotFoundException e) { filePathCallback.onReceiveValue(null); return false; } return true; } }); // 加载你的目标网页 webView.loadUrl("你的网页地址"); }
确认Manifest权限配置正确
确保你的AndroidManifest.xml中已经正确声明权限,注意给旧权限加上maxSdkVersion避免影响Android 13+:
<!-- Android 13+ 媒体权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- Android 12及以下 存储权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
总结
必须修改MainActivity的代码,因为Android 13的媒体权限要求动态申请,仅Manifest声明不会触发权限弹窗。上面的代码实现了从Android 5.0到13的权限兼容逻辑,同时保证WebView能正确唤起文件选择器,解决权限弹窗不显示的问题。
内容的提问来源于stack exchange,提问作者codershhoder
相关产品推荐
相关产品推荐

