可能是因为在 Android 11 中新增了一些安全限制,需要进行额外的配置才能使 Webview 能够调用 Android 的方法。

你可以尝试按照以下步骤进行配置:

  1. 在 AndroidManifest.xml 文件中添加以下权限:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
  1. 在应用的 build.gradle 文件中添加以下配置:
android {
    // ...
    defaultConfig {
        // ...
        // 允许 Webview 访问应用的文件和目录
        manifestPlaceholders = [
            'appPackageName': "${applicationId}",
            'permissions': "${packageName}.permission.C2D_MESSAGE"
        ]
    }
    // ...
}

// 允许 Webview 访问应用的文件和目录
task grantWebViewPermissions {
    doLast {
        android.applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def packageName = output.packageName
                def packageDir = "${output.outputFile.parent}/data/app/${packageName}-*/"
                
                // 允许 Webview 访问应用的文件和目录
                exec {
                    commandLine "adb", "shell", "sh", "-c", "pm grant ${packageName} android.permission.QUERY_ALL_PACKAGES && pm grant ${packageName} android.permission.MANAGE_EXTERNAL_STORAGE && pm grant ${packageName} ${packageName}.permission.C2D_MESSAGE && find ${packageDir} -type d -exec chmod 755 {} + && find ${packageDir} -type f -exec chmod 644 {} +"
                }
            }
        }
    }
}
  1. 在 WebView 的 setWebChromeClient 方法中添加以下配置:
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        // 获取应用的包名
        PackageManager pm = webView.getContext().getPackageManager();
        String packageName = webView.getContext().getPackageName();

        // 允许 Webview 访问应用的文件和目录
        String[] permissions = new String[]{
                Manifest.permission.QUERY_ALL_PACKAGES,
                Manifest.permission.MANAGE_EXTERNAL_STORAGE,
                packageName + ".permission.C2D_MESSAGE"
        };
        ActivityCompat.requestPermissions(MainActivity.this, permissions, 0);

        // 支持调用 Android 的方法
        if (message.startsWith("callAndroidMethod:")) {
            String methodName = message.substring("callAndroidMethod:".length());
            try {
                Method method = MainActivity.this.getClass().getDeclaredMethod(methodName);
                method.setAccessible(true);
                result.confirm((String) method.invoke(MainActivity.this));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        }

        return super.onJsPrompt(view, url, message, defaultValue, result);
    }
});
  1. 在 MainActivity 中添加一个公开的方法,供 WebView 调用:
public String getHello() {
    return "Hello, Android!";
}

这样就可以使 WebView 正常调用 Android 的方法了


原文地址: https://www.cveoy.top/t/topic/cyoY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录