英文:
WebView not launching new tab with external URL
问题
I can provide a translation of the code section you provided:
webView.settings.setSupportZoom(true)
webView.settings.javaScriptEnabled = true
webView.settings.offscreenPreRaster = true
webView.settings.setSupportMultipleWindows(true)
webView.settings.javaScriptCanOpenWindowsAutomatically = true
webView.addView(newWebView)
webView.webChromeClient = object : WebChromeClient() {
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
val newWebView = WebView(requireActivity())
newWebView.settings.setSupportZoom(true)
newWebView.settings.loadWithOverviewMode = true
newWebView.settings.javaScriptEnabled = true
newWebView.settings.offscreenPreRaster = true
newWebView.settings.setSupportMultipleWindows(true)
newWebView.settings.javaScriptCanOpenWindowsAutomatically = true
newWebView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
// Starts loading
super.onPageStarted(view, url, favicon)
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
// Never called
val newUrl = request?.url?.toString()
val browserIntent = Intent(Intent.ACTION_VIEW)
browserIntent.data = Uri.parse(newUrl)
startActivity(browserIntent)
return true
}
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
// Never called
handler?.proceed()
}
}
val transport = resultMsg?.obj as? WebView.WebViewTransport
transport?.webView = newWebView
resultMsg?.sendToTarget()
return true
}
}
Please note that the code you provided is written in Kotlin and is related to WebView configuration. If you need further assistance or have specific questions about this code, feel free to ask.
英文:
I'm running into an issue where entering a bank account triggers an Authenticate pop-up for users inside a WebView. This pop-up is controlled via Stripe.js. Currently, the "Auth" button is shown but nothing happens when the user clicks on it. I can see that the onPageStarted
is triggered via the WebViewClient with the url. The user receives an OTP via SMS, but because nothing happens they have nowhere to enter it.
On Chrome, the Auth button opens a new tab where it loads a page for the user to enter the OTP. Why is this new page not loading given the code below? Am I adding the new WebView correctly? I don't see any documentation on this. This is the only example I've found https://stackoverflow.com/a/27010225/1649472
webView.settings.setSupportZoom(true)
webView.settings.javaScriptEnabled = true
webView.settings.offscreenPreRaster = true
webView.settings.setSupportMultipleWindows(true)
webView.settings.javaScriptCanOpenWindowsAutomatically = true
webView.addView(newWebView)
webView.webChromeClient = object : WebChromeClient() {
override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message?): Boolean {
val newWebView = WebView(requireActivity())
newWebView.settings.setSupportZoom(true)
newWebView.settings.loadWithOverviewMode = true
newWebView.settings.javaScriptEnabled = true
newWebView.settings.offscreenPreRaster = true
newWebView.settings.setSupportMultipleWindows(true)
newWebView.settings.javaScriptCanOpenWindowsAutomatically = true
newWebView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
// Starts loading
super.onPageStarted(view, url, favicon)
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
// Never called
val newUrl = request?.url?.toString()
val browserIntent = Intent(Intent.ACTION_VIEW)
browserIntent.data = Uri.parse(newUrl)
startActivity(browserIntent)
return true
}
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
// Never called
handler?.proceed()
}
}
val transport = resultMsg?.obj as? WebView.WebViewTransport
transport?.webView = newWebView
resultMsg?.sendToTarget()
return true
}
}
答案1
得分: 1
Inside onCreateWindow
you have handle where to display the new childWebview. resultMsg
and WebViewTransport
is to actually connect the separate webview into one window relationship. To note that, adding view to webView is unsupported, so you have to display the webview elsewhere. For example, by adding a new webView to the LinearLayout
that wraps the entire fragmentView.
To summarize the comment and example, below is a minimum functional example of opening a new window:
class WebExampleFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = WebView(inflater.context).apply {
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver{ _, event ->
when (event) {
Lifecycle.Event.ON_PAUSE -> onPause()
Lifecycle.Event.ON_RESUME -> onResume()
Lifecycle.Event.ON_DESTROY -> destroy()
else -> {}
}
})
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val webView = view as WebView
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.javaScriptCanOpenWindowsAutomatically = true
webView.settings.setSupportMultipleWindows(true)
webView.webViewClient = WebViewClientCompat()
webView.webChromeClient = object: WebChromeClient() {
override fun onCreateWindow(view: WebView, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message): Boolean {
val transport = resultMsg.obj as WebViewTransport
val childWebView = WebView(view.context)
childWebView.settings.useWideViewPort = true
childWebView.webViewClient = WebViewClientCompat()
val dialog = MaterialAlertDialogBuilder(view.context)
.setView(childWebView).create()
transport.webView = childWebView
childWebView.webChromeClient = object: WebChromeClient() {
override fun onCloseWindow(window: WebView) {
if (window === childWebView) {
dialog.dismiss()
}
}
}
resultMsg.sendToTarget()
dialog.show()
return true
}
}
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.withResumed {
webView.evaluateJavascript("""
window.open("https://www.google.com");
""".trimIndent(), null)
}
}
}
}
[![enter image description here][1]][1]
[![enter image description here][1]][1]
<details>
<summary>英文:</summary>
Inside `onCreateWindow` you have handle where to display the new childWebview. `resultMsg` and `WebViewTransport` is to actually connect the separate webview into one window relation ship.
To note that, adding view to webView is unsupported. so you have display the webview else where. For example, adding new webView to the `LinearLayout` that is wrapping the whole fragmentView.
To summarize the comment and example. Below is minimum functional example of opening new window.
class WebExampleFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = WebView(inflater.context).apply {
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver{ _, event ->
when (event) {
Lifecycle.Event.ON_PAUSE -> onPause()
Lifecycle.Event.ON_RESUME -> onResume()
Lifecycle.Event.ON_DESTROY -> destroy()
else -> {}
}
})
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val webView = view as WebView
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.settings.javaScriptCanOpenWindowsAutomatically = true
webView.settings.setSupportMultipleWindows(true)
webView.webViewClient = WebViewClientCompat()
webView.webChromeClient = object: WebChromeClient() {
override fun onCreateWindow(view: WebView, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message): Boolean {
val transport = resultMsg.obj as WebViewTransport
val childWebView = WebView(view.context)
childWebView.settings.useWideViewPort = true
childWebView.webViewClient = WebViewClientCompat()
val dialog = MaterialAlertDialogBuilder(view.context)
.setView(childWebView).create()
transport.webView = childWebView
childWebView.webChromeClient = object: WebChromeClient() {
override fun onCloseWindow(window: WebView) {
if (window === childWebView) {
dialog.dismiss()
}
}
}
resultMsg.sendToTarget()
dialog.show()
return true
}
}
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.withResumed {
webView.evaluateJavascript("""
window.open("https://www.google.com");
""".trimIndent(), null)
}
}
}
}
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/qEOI1.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论