问题
I'm trying to make a app with WebView, but the website is using https, but the content (ex. mp3 file) uses http, so Android Lollipop won't load it because it is "Mixed Content". I tried to use onReceivedSslError handler.proceed();, but it doesn't load anything. Is there a way to fix it? or could I just make all websites loaded use http, so It doesn't show any errors?
回答1:
Since Pie (API 29), all non-HTTPS traffic in app is now disabled by default.
If you're targeting API level 26 or above, you must first enable it in the manifest file. Add
android:usesCleartextTraffic="true"
into <application> tag.
Since Lollipop (API 21), WebView blocks all mixed content by default.
To change this behaviour, when you are targeting API level 21 or above, use:
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
In this mode, the WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content. Some insecure content may be allowed to be loaded by a secure origin and other types of content will be blocked. The types of content are allowed or blocked may change release to release and are not explicitly defined.
In practice this should allow loading of images, videos, music etc. - all content that has low probability of being major security threat, when tampered/replaced by malicious third-party.
Alternatively use (strongly discouraged):
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
In this mode, the WebView will allow a secure origin to load content from any other origin, even if that origin is insecure. This is the least secure mode of operation for the WebView, and where possible apps should not set this mode.
回答2:
If your min API is less than 21 and cannot call setMixedContentMode directly, you can use reflection:
try {
Method m = WebSettings.class.getMethod("setMixedContentMode", int.class);
if ( m == null ) {
Log.e("WebSettings", "Error getting setMixedContentMode method");
}
else {
m.invoke(webView.getSettings(), 2); // 2 = MIXED_CONTENT_COMPATIBILITY_MODE
Log.i("WebSettings", "Successfully set MIXED_CONTENT_COMPATIBILITY_MODE");
}
}
catch (Exception ex) {
Log.e("WebSettings", "Error calling setMixedContentMode: " + ex.getMessage(), ex);
}
回答3:
In android pie in addition to setting the mixed content mode, you also need to set the android:usesCleartextTraffic attribute in the AndroidManifest.
In your AndroidManifest.xml do:
<application
....
android:usesCleartextTraffic="true"
...>
and when setting up the webview, do:
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
回答4:
to load it conditionally on API >= 21, you don't have to use reflection.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
}
回答5:
I've recently migrated from Crosswalk to use the native WebView.
Had to fight with this issue for a few hours. The fix was to run clearCache() prior to setting the settings.
webView.clearCache(false); // <-- DO THIS FIRST
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
来源:https://stackoverflow.com/questions/32155634/android-webview-not-loading-mixed-content