android - setwebchromeclient - Error en la vista web con targetSdkVersion 24
webview evaluatejavascript (1)
Después de algunas semanas, descubrí este https://developer.android.com/about/versions/android-5.0-changes.html#BehaviorWebView que explica los cambios de api 21. Eche un vistazo a la parte de WebView
que dice:
Si su aplicación funciona con API nivel 21 o posterior:
- El sistema bloquea por defecto el contenido mixto y las cookies de terceros. Para permitir contenido mixto y cookies de terceros, use los métodos
setMixedContentMode () y setAcceptThirdPartyCookies (), respectivamente.
Entonces, solo agregué estas configuraciones en WebView
y funcionó perfectamente.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
}
Mi aplicación tiene un WebView
que carga una página HTML simple con un iFrame que se utiliza para cargar una URL para el proceso de pago de una empresa asociada (y no tengo acceso a esa fuente de la url).
Cuando targetSdkVersion
a 19 todo funciona bien y puedo realizar pagos a través del iFrame. Sin embargo, cuando targetSdkVersion
apunta a 24, no tengo la misma suerte.
En ese caso, WebView
logra cargar el iFrame que se muestra con EditText
para ingresar con información de tarjeta de crédito y un Button
para enviarlo, pero siempre tengo un error 500 cuando hago clic en ese botón.
Dado que la URL de pago se subcontrata, llegué a nuestra empresa asociada para conocer el origem del error 500. Y me dijeron que el error proviene de una doble llamada que me hace pensar que algo en el WebView
de api 24 lo está haciendo.
El archivo HTML
payment_html
es el siguiente:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
</head>
<body id="bodyContent" onload="addListener()" style="margin:0px;padding:0px;overflow:hidden;height:355px">
<iframe id="ifrPagamento" src="partner_url"
frameborder="0" style="overflow:hidden;width:100%;height:100%"></iframe>
</body>
<script type="text/javascript">
function addListener() {
window.addEventListener("message", receiveMessage, false);
}
function receiveMessage(message) {
if (message) {
var data = JSON.parse(message.data);
if (data.code) {
if(data.code === "0") {
app.returnStatus(0);
}
else {
app.returnStatus(1);
}
}
}
}
</script>
</html>
El partner_url
se reemplaza por el URL de la empresa asociada y lo obtengo dinámicamente como sigue:
private void loadPage() {
String url = (String) Session.getObject(Session.Key.PARTNER_URL, "");
InputStream inputStream = mActivity.getResources().openRawResource(R.raw.payment_html);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
int i = inputStream.read();
while (i != -1) {
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
String html = byteArrayOutputStream.toString();
html = html.replace("partner_url", url);
mWebView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null);
} catch (IOException e) {
Funcoes.printError(e.getMessage());
}
}
Configuro WebView
como el siguiente:
private void setupWebView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webSettings.setAppCacheEnabled(false);
webSettings.setDomStorageEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mWebView.addJavascriptInterface(new MyJavaScriptInterface(mActivity), "app");
mWebView.setWebViewClient(new WebViewClient() {
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
return true;
}
});
}
Y finalmente el layout.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:background="@color/white">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
</WebView>
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"/>
</RelativeLayout>
Como dije antes, no tengo la fuente de la URL porque está subcontratada. Entonces no puedo compartirlo.
He estado luchando con este tema durante un par de semanas. ¿Alguien puede ayudarme?