Android WebView如何实现权限授予完成后再立即加载URL
问题根源
原有实现无法生效的核心原因有三点:
- 权限请求码不匹配:发起权限申请时传入的requestCode为
contact_perm,但onRequestPermissionsResult回调中判断的匹配值为1,授权完成后的逻辑分支根本不会被触发 - 授权结果校验逻辑不全:回调中仅判断了
grantResults数组第一个元素的授权状态,没有校验所有申请的权限是否全部通过,不满足「全部权限授予后才加载」的要求 - 初始加载未做拦截:初始化阶段没有阻断WebView的默认加载逻辑,导致权限申请和页面加载并行执行,授权完成前页面已经开始加载,无法拿到需要传入的位置等数据
实现步骤
- 定义统一的权限请求码常量,保证权限申请、回调校验两个环节使用的请求码完全一致
- 应用初始化阶段先完成WebView基础配置,但绝对不调用
loadUrl方法 - 启动时统一校验所有必需权限的授权状态:如果全部权限已授予,直接执行位置获取、URL加载逻辑;如果存在未授权的权限,批量发起权限申请,等待用户操作
- 权限回调中遍历所有授权结果,确认所有权限均被授予后,再执行位置获取、URL加载逻辑;如果存在被拒绝的权限,可弹出对应提示引导用户授权
可直接复用的代码实现
// 统一权限请求码,可根据自己的业务调整值,只要保证申请和回调判断一致即可 private static final int REQ_ALL_PERMISSIONS = 1001; private WebView asw_view; private String targetUrl = "你的目标WebView地址"; // 所有必需权限列表 private final String[] requiredPermissions = new String[]{ Manifest.permission.READ_CONTACTS, Manifest.permission.POST_NOTIFICATIONS, Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_PHONE_NUMBERS, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 仅初始化WebView基础配置,不要提前加载URL asw_view = findViewById(R.id.asw_view); asw_view.getSettings().setJavaScriptEnabled(true); // 其他WebView配置按业务需求添加... // 启动时先做权限校验 if (hasAllPermissions()) { loadTargetPage(); } else { // 存在未授权权限,发起申请,不执行加载 ActivityCompat.requestPermissions(this, requiredPermissions, REQ_ALL_PERMISSIONS); } } // 校验所有必需权限是否已全部授予 private boolean hasAllPermissions() { for (String perm : requiredPermissions) { if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } // 统一的页面加载入口,避免多入口提前加载 private void loadTargetPage() { get_location(); asw_view.loadUrl(targetUrl); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQ_ALL_PERMISSIONS) { boolean allPermGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allPermGranted = false; break; } } if (allPermGranted) { // 全部权限授予完成,再加载页面 loadTargetPage(); } else { // 权限被拒绝的提示,可根据业务调整 Toast.makeText(this, "需授予全部必需权限才能正常使用应用功能", Toast.LENGTH_SHORT).show(); } } }
适配注意事项
- 如果应用
targetSdkVersion >= 33,READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE在Android 13及以上系统已失效,需要根据业务场景替换为对应的照片、视频、音频类读取权限,否则对应权限申请会直接返回拒绝 - 如果用户勾选「不再询问」拒绝权限,后续不会再弹出系统授权弹窗,需要增加引导逻辑,提示用户跳转到应用设置页手动开启权限
- 所有WebView加载逻辑统一收口到
loadTargetPage方法中,不要在其他生命周期或初始化逻辑中提前调用loadUrl,避免出现权限未完成就加载的问题
内容的提问来源于stack exchange,提问作者Ahamed
相关产品推荐
相关产品推荐

