I need to load a proper site into webview.
What I do:
webView.setInitialScale(1)
webView.webViewClient = MyWebViewClient()
webView.settings.allowFileAccess = true
webView.settings.pluginState = WebSettings.PluginState.ON
webView.settings.pluginState = WebSettings.PluginState.ON_DEMAND
webView.settings.javaScriptEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.useWideViewPort = true
for site
webView.loadUrl("https://pnpcss.com/vxyfv2ey/?subId1=fonev")
custom WebView:
private class MyWebViewClient : WebViewClient() {
#TargetApi(Build.VERSION_CODES.N)
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
view.loadUrl(request.url.toString())
return true
}
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView?, url: String?) {
CookieManager.getInstance().getCookie(url)
super.onPageFinished(view, url)
}
}
What I have:
Only the bottom part of site is loaded, the upper is not. If I use chrome on this android phone, it is loaded ok.
Android versions tested: 5.0.1 & 8.
What I do wrong?
The problem was in that iframe was not loaded. It is solved with settings.domStorageEnabled = true
Related
I have a WebView in my app. But when the website behavior is to open a modal, the webview redirects me to a blank screen. I put logs in onPageStarted and shouldOverrideUrlLoading, and saw that it doesn't fit in either method.
webview.settings.javaScriptEnabled = true
webview.settings.domStorageEnabled = true
webview.settings.javaScriptCanOpenWindowsAutomatically = true
webview.settings.setSupportMultipleWindows(true)
webview.settings.allowFileAccess = true
webview.setWebChromeClient(object : WebChromeClient() {
#SuppressLint("SetJavaScriptEnabled")
override fun onCreateWindow(
view: WebView?,
isDialog: Boolean,
isUserGesture: Boolean,
resultMsg: Message
): Boolean {
val newWebView = WebView(context)
val webSettings = newWebView.settings
webSettings.javaScriptEnabled = true
// Other configuration comes here, such as setting the WebViewClient
val dialog = Dialog(context!!)
dialog.setContentView(newWebView)
dialog.show()
newWebView.setWebChromeClient(object : WebChromeClient() {
override fun onCloseWindow(window: WebView) {
dialog.dismiss()
}
})
(resultMsg.obj as WebViewTransport).webView = newWebView
resultMsg.sendToTarget()
return true
}
})
webview.setWebViewClient(object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
}
override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
webView.loadUrl(url)
return true
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
Handler().postDelayed({
if(progressBar!=null)
progressBar.visibility = View.GONE
}, 3500)
}
})
webview.loadUrl(url)
I also tried to redirect it to the chrome client if it was going to open the modal, but as it doesn't load any new urls, I don't think it's overwriting the method
I wanna provide a custom browser inside app to the user could pass authorization on GitHub.com. But Authorize button is disabled in WebView.
I set recommended flags from other questions on stackoverflow but it didn't help. There is my ViewModel below where you can see flags and clients that I set for WebView:
class LoginViewModel : ViewModel() {
var url: ObservableField<String> = ObservableField()
var isLoading: ObservableBoolean = ObservableBoolean()
val webViewClient: WebViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view?.loadUrl(url)
return true
}
override fun onReceivedError(
view: WebView, request: WebResourceRequest,
error: WebResourceError
) {
super.onReceivedError(view, request, error)
isLoading.set(false)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
isLoading.set(false)
}
}
val webChromeClient: WebChromeClient = WebChromeClient()
val webViewConfig: IWebViewConfig = object : IWebViewConfig {
override fun onConfig(webView: WebView) {
webView.settings.domStorageEnabled = true
webView.settings.databaseEnabled = true
webView.settings.javaScriptEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.useWideViewPort = true
webView.settings.allowContentAccess = true
webView.settings.allowFileAccess = true
webView.settings.allowFileAccessFromFileURLs = true
webView.settings.allowUniversalAccessFromFileURLs = true
webView.settings.userAgentString = "Android"
}
}
fun onRefresh() {
isLoading.set(true)
url.notifyChange()
}
}
Where can the problem be?
I created an android WebView and open my website who server with https and authentication redirection anyway this work successfully in all of modern browsers like opera, chrome, Firefox , edge and eth but in android WebView i got 'too many redirect' error
By the way when I set WebView cache mode to none, this error had gone, but i need the cache mode,
Any body can help me?
Use this code to initialize webview and set url, it is work fine with me with all Android versions
#SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
webView.settings.javaScriptEnabled = true
webView.settings.loadsImagesAutomatically = true
webView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
private fun webViewListener() {
webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
Log.d(TAG, url)
}
override fun onReceivedError(view: WebView, request: WebResourceRequest,
error: WebResourceError) {
super.onReceivedError(view, request, error)
//Error load url
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
//Loading url
view?.loadUrl(url)
return true
}
}
}
Add this line in Manifest File
<application
...
android:usesCleartextTraffic="true">
You can read more about usesCleartextTraffic
I am making an Android browser app, I want to handle link click that has target='_blank', which will open in a new tab in normal browsers.
There is a method call onCreateWindow in WebChromeClient which is triggering when a _blank link clicked. But my question is how can I get the link URL? following code is just returning the current URL
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
Toast.makeText(context, view?.url, Toast.LENGTH_LONG).show()
return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg)
}
Finally, I found a way to capture the link URL.
#SuppressLint("SetJavaScriptEnabled")
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
val newWebView = WebView(context)
addView(context, newWebView)
val transport = resultMsg?.obj as WebView.WebViewTransport
transport.webView = newWebView
val settings = newWebView.getSettings()
settings.javaScriptEnabled = true
settings.javaScriptCanOpenWindowsAutomatically = true
settings.setSupportMultipleWindows(true)
settings.useWideViewPort = false
newWebView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
Toast.makeText(context, url, Toast.LENGTH_LONG).show()
super.onPageStarted(view, url, favicon)
}
}
resultMsg.sendToTarget()
return true
}
By creating a new web and adding it to the WebViewTransport, you can add a new WebViewClient to that new WebView then its easy to capture that URL from onPageStarted method.
Solution must work on API >20
This solution does not work. I assume it works only on lower versions of the Android API. I'm testing on Android 8.0.
I've tried using Retrofit as soon as the page is loaded, instead of getting the html via WebViewClient. But the user is not logged in in the Retrofit request. And I'm doing the same request 2 times then.
#SuppressLint("JavascriptInterface")
private fun initializeWebView(url : String?) {
binding.webView.loadUrl(url)
binding.webView.settings.javaScriptEnabled = true
binding.webView.settings.useWideViewPort = true
binding.webView.requestFocus(View.FOCUS_DOWN)
binding.webView.addJavascriptInterface(MyJavaScriptInterface(context!!), "HtmlViewer");
binding.webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
return false
}
override fun onPageFinished(view: WebView?, url: String?) {
// super.onPageFinished(view, url)
//tried adding a sleep, but doesn't work:
Thread.sleep(6000)
//showHTML method is not being called:
binding.webView.loadUrl("javascript:window.HtmlViewer.showHTML" +
"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');")
// Prints out: html: null
binding.webView.evaluateJavascript(
"javascript:window.HtmlViewer.showHTML" +
"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');"
) { html ->
Log.d("HTML", html)
// code here
}
}
}
}
class MyJavaScriptInterface(val context: Context) {
fun showHTML(html: String) {
Log.d("",""+html)
AlertDialog.Builder(context).setTitle("HTML").setMessage(html)
.setPositiveButton(android.R.string.ok, null).setCancelable(false).create().show() }
}