我试图为 webview 应用程序创建 Google Auth 登录。 它的工作原理如下
用户点击应用程序中的“使用 Google 登录”按钮,将打开默认/Chrome 浏览器,显示所有已登录的 Google 帐户进行登录。
用户选择帐户,继续,然后使用 App:// 链接,我可以将用户重定向回我的应用程序,并且还可以读取传递的 URL 参数。
包 com.webviewtemplate.webviewtemplate
导入 android.annotation.SuppressLint 导入 android.app.Activity 导入 android.os.Build 导入 android.os.Bundle 导入 android.webkit.WebView 导入 android.window.OnBackInvokedDispatcher 导入 com.webviewtemplate.webviewtemplate.databinding.ActivityMainBinding
MainActivity 类:Activity() { // 要加载的网页的 URL 私有val applicationUrl =“https://fieldops.testurl.com/app.html”
private lateinit var binding: ActivityMainBinding
private lateinit var webView: WebView
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
webView = binding.webView
// Handle the intent and extract query parameters if present
val intent = intent
val data = intent.data
var targetUrl = applicationUrl
if (data != null && data.scheme == "myapp") {
// Extract the 'code' parameter from the incoming intent
val code = data.getQueryParameter("code")
if (!code.isNullOrEmpty()) {
// Append the code to the application URL as a query parameter
targetUrl = "$applicationUrl?code=$code"
}
}
// Enable necessary WebView settings
webView.settings.domStorageEnabled = true
webView.settings.javaScriptEnabled = true
// Handle back navigation for WebView
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT
) {
if (webView.canGoBack()) {
webView.goBack()
} else {
finish()
}
}
}
// Load the target URL into the WebView
webView.loadUrl(targetUrl)
}
}
所以 Google Auth 工作正常,问题出在 webview 应用程序中,主域/URL 仅在启动时打开,之后无论我点击哪里,它都会在 Chrome 上打开。
相反,我想在 webview 应用程序内打开 mail/give 域内的所有 URL,以及 Chrome/默认浏览器中的所有其他 URL。
我尝试了很多方法,但所有方法都有效,但是对于外部链接,它会打开一个不同的 Chrome 会话,在其中我看不到任何登录的 Google 帐户,并且 app:// 链接不起作用 - 所以即使我输入我的 Google 凭据,它不会重定向回 webview 应用程序。
如何通过 webview 应用程序触发来正确使用 chrome 的默认会话?
private lateinit var binding: ActivityMainBinding
private lateinit var webView: WebView
private val applicationUrl = "https://yourapp.com" // Your default application URL
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
webView = binding.webView
// Handle the intent and extract query parameters if present
val intent = intent
val data = intent.data
var targetUrl = applicationUrl
if (data != null && data.scheme == "myapp") {
// Extract the 'code' parameter from the incoming intent
val code = data.getQueryParameter("code")
if (!code.isNullOrEmpty()) {
// Append the code to the application URL as a query parameter
targetUrl = "$applicationUrl?code=$code"
}
}
// Enable necessary WebView settings
webView.settings.domStorageEnabled = true
webView.settings.javaScriptEnabled = true
// Set a custom WebViewClient to intercept URL requests and keep everything inside the WebView
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
// Override URL loading to keep it inside WebView
if (request != null) {
view?.loadUrl(request.url.toString())
}
return true // Return true to prevent the URL from opening in the browser
}
// Optional: Handle URLs that WebView cannot load (e.g., when WebView is not able to handle the link)
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: android.webkit.WebResourceError?) {
super.onReceivedError(view, request, error)
// You can show an error message here or take appropriate action
}
}
// Optional: Set a WebChromeClient if you need features like JavaScript alert boxes, etc.
webView.webChromeClient = WebChromeClient()
// Handle back navigation for WebView (custom back stack logic)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT
) {
if (webView.canGoBack()) {
webView.goBack()
} else {
finish()
}
}
}
// Load the target URL into the WebView
webView.loadUrl(targetUrl)
}
webView.webViewClient = 对象: WebViewClient() { 覆盖乐趣 shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { 如果(请求!= null){ view?.loadUrl(request.url.toString()) // 将 URL 保留在 WebView 中 } return true // 阻止 URL 在浏览器中打开 } }