android – 如何检查 webview 是否可用?

kla*_*ter 3 android webview

有没有办法检查设备上是否可以使用 webview?

背景:如果我添加<uses-feature android:name="android.software.webview"/>到 Manifest,Google Play 上支持的设备数量将从 12,000 多台下降到 6,000 台以下。所以我添加android:required="false"了这个功能。如果 webview 可用,网站应显示在应用程序内,否则在默认浏览器中启动:

String mUrl = "http://www.example.com";
if (*** WHAT TO PUT HERE? ***) {
    WebView webview = (WebView) findViewById(R.id.webView);
    if (Build.VERSION.SDK_INT >= 24) {
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(request.toString());
                return false;
            }
        });
    } else {
        webview.setWebViewClient(new WebViewClient() {
            @SuppressWarnings("deprecation")
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return false;
            }
        });
    }
    webview.loadUrl(mUrl);
} else {
    Uri uri = Uri.parse(mUrl);
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}
Run Code Online (Sandbox Code Playgroud)

编辑(使事情清楚):<uses-permission android:name="android.permission.INTERNET" />是(并且一直是)清单的一部分。只是添加<uses-feature android:name="android.software.webview" />会导致支持的设备下降。

这里有人有同样的问题:https : //issuetracker.google.com/issues/37035282 (不幸的是没有回答)

Tor*_*ure 10

替代解决方案:
val hasWebView: Boolean = kotlin.runCatching { CookieManager.getInstance() }.isSuccess

它之所以有效,是因为如果 WebView 不可用,则会CookieManager.getInstance()抛出AndroidRuntimeException

getPackageManager().hasSystemFeature("android.software.webview")不可靠。如果设备应该有网络视图,但在系统设置中禁用了它,它将返回 true。

我在华为 P20 上进行了测试,方法是转到“设置”->“应用程序”->“Android 系统 WebView”->“禁用”


小智 7

虽然@vsatkh 指出不一定需要按要求声明这个特性,但你可以通过如下方式检查设备的特性兼容性:

getPackageManager().hasSystemFeature("android.software.webview")
Run Code Online (Sandbox Code Playgroud)

此方法返回真或假。

关于 Google Play 过滤的一些附加信息:Google Play 仅根据<uses-feature>清单中声明的​​元素过滤受支持的设备。<uses-permission>元素不会影响 Google Play 的过滤,除非它们暗示某项功能。android.permission.INTERNET不暗示任何特征。此处列出了暗示功能的权限:https : //developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions

  • 使用 API 20 及更高版本,您可以使用 `PackageManager.FEATURE_WEBVIEW` 而不是硬编码字符串。 (3认同)

Roh*_*ngh 7

有一种解决方法:CookieManager

AFAIK:没有专门的 API 可以为您提供该信息。但如果我告诉你有办法解决呢?

正如 Torkel 提到的,getPackageManager().hasSystemFeature(..)不保证告诉 Android 系统 WebView 是启用还是禁用。

即使用户在“设置”中禁用 WebView,getPackageManager().hasSystemFeature(..) 仍将返回 true。

Cookie管理器

因此,另一种选择是使用CookieManager.
应用程序 WebView cookie 由 管理CookieManager。如果您在禁用 WebView 时尝试创建 CookieManager 实例,则会引发异常。

在 Kotlin 中,您可以从块语句中获取结果,但在 Java 中则不可能。所以你可以使用函数中的异常处理逻辑来决定。

这是一个例子

public boolean webViewEnabled(){

    try{

       CookieManager.getInstance();
       return true;

    }catch(Exception e){

       return false;

    }

}
Run Code Online (Sandbox Code Playgroud)

笔记:

当前的实现将来可能会发生变化,或者他们可能会为此提供专用的 API。我尝试在许多论坛中找到完美的解决方案,但这是我达到的最接近的解决方案。
此解决方案将防止您的应用程序崩溃,但您仍然会在日志中看到错误,因为 CookieManager.getInstance 会抛出 Exception 对象。