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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:00:09