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.
Related
I'm trying to embed a webview which embed an url which use a personal certificate to authenticate in the web. If I use a normal Chrome, when I reach this point, a system dialog appears to select the certificate but when I tried on the webview, when I reach this point of the system dialog, the web fails with message that cannot access.
Is it possible to do that? This is my code for the webview.
val myWebView: WebView = findViewById(R.id.wv)
myWebView.loadUrl(url)
myWebView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return false
}
}
myWebView.webChromeClient = object : WebChromeClient () {
override fun onJsAlert(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
return super.onJsAlert(view, url, message, result)
}
override fun onJsConfirm(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
return super.onJsConfirm(view, url, message, result)
}
override fun onJsPrompt(
view: WebView?,
url: String?,
message: String?,
defaultValue: String?,
result: JsPromptResult?
): Boolean {
return super.onJsPrompt(view, url, message, defaultValue, result)
}
}
myWebView.settings.javaScriptCanOpenWindowsAutomatically = true
myWebView.settings.javaScriptEnabled = true
myWebView.settings.loadsImagesAutomatically = true
myWebView.settings.loadWithOverviewMode = true
myWebView.settings.domStorageEnabled = true
myWebView.settings.builtInZoomControls = true
myWebView.settings.allowContentAccess = true
Thanks
The Webview is likely using the network security policy of your app, while Chrome is using the system's policy. If this is the case, you can embed your custom cert in the app and add a network_security_config.xml that defines it as trusted. See here for details.
Here is my code and it's working in demo project but not in my project. I am trying to add these parameters through webView Client but it is showing from mnemonics not found.
fun sendTrx(c:Context, from_address: String, fromMnemonics: String, amount: String, toAddress: String) {
mycontext=c
var webvw = WebView(mycontext)
webvw.addJavascriptInterface(this, "Android")
webvw.settings.javaScriptEnabled = true
webvw.settings.domStorageEnabled=true
webvw.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
getCustomHeaders()?.let { view!!.loadUrl(request!!.url.toString(), it) };
return true;
}
}
webvw.loadUrl("file:///android_asset/send.html")
val amtChanged = amount.toDouble() * 1000000000000
val amtTobeTransferred = BigDecimal(amtChanged).toBigInteger()
webvw.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
webvw.loadUrl("javascript:from_address(\"$from_address\")")
webvw.loadUrl("javascript:fromMnemonics(\"$fromMnemonics\")")
webvw.loadUrl("javascript:amtTobeTransferred(\"$$amtTobeTransferred\")")
webvw.loadUrl("javascript:toAddress(\"$toAddress\")")
// webvw.loadUrl("javascript:toAddress(\"$toAddress\")")
}
}
check in your javascript code that you have field/ method named "fromMnemonics" or not
Some time page with poster thumbnail throws null pointer exception in web view[Andoid].
I have already tried this code.
`lateinit var webView: WebView
webView = view.findViewById(R.id.webView) as WebView
webView.settings.javaScriptEnabled = true
webView.isHorizontalScrollBarEnabled = false
webView.postDelayed({ webView.loadUrl(url) }, 100)
webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
progressLayout.visibility = View.VISIBLE
}
override fun onPageFinished(view: WebView, url: String) {
// do your stuff here
progressLayout.visibility = View.INVISIBLE
homeScreenImage.visibility = View.GONE
}
}`
Please try this if it works
you can use web chrome client and override default video poster and load default bitmap in case of loading fails
webView.webChromeClient = object : WebChromeClient() {
override fun getDefaultVideoPoster(): Bitmap? {
val result = super.getDefaultVideoPoster()
return result ?: Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)
}
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
}
}
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 have a link to the PDF or XML file. By default, a web view doesn't render such links. From another StackOverflow post, I figured out I need to wrap by link by google doc or google drive link (http://docs.google.com/viewer?url=myPDFLink). It works, the web view displays content but not in all cases. For the same link, the content randomly might be not displayed or be displayed. If the page is not displayed I can just retry several times and content displays. Cannot find a reason for such behavior. Even if the web view is blank, the onPageFinished callback is being called but not any error callbacks.
Update: onPageStarted is not being called but onPageFinished is being
WebViewClient:
val webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
updateOnBackPressedCallbackState()
toolbarActivity?.setToolBarTitle(url)
onPageStateListener?.onPageStarted(view, url)
}
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
progressBar?.visibility = View.GONE
toolbarActivity?.setToolBarTitle(view.title)
onPageStateListener?.onPageFinished(view)
}
override fun onReceivedError(
view: WebView?,
errorCode: Int,
description: String?,
failingUrl: String?
) {
super.onReceivedError(view, errorCode, description, failingUrl)
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
super.onReceivedError(view, request, error)
}
override fun onReceivedHttpError(
view: WebView?,
request: WebResourceRequest?,
errorResponse: WebResourceResponse?
) {
super.onReceivedHttpError(view, request, errorResponse)
}
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) {
super.onReceivedSslError(view, handler, error)
}
}
Settings:
webViewer.webViewClient = webViewClient
webViewer.settings.javaScriptEnabled = true
webViewer.isHorizontalScrollBarEnabled = true
webViewer.settings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
Try to handle SSL errors within onReceivedSslError to proceed with the certificate
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler?,
error: SslError?
) =
if (handler != null) {
handler.proceed()
} else {
super.onReceivedSslError(view, handler, error)
}