package com.example.mylibrary import android.app.Activity import android.app.Application import android.content.ComponentCallbacks import android.content.Context import android.content.Intent import android.content.res.Configuration import android.graphics.Color import android.os.Build import android.os.Bundle import android.util.Log import android.view.View import android.webkit.CookieManager import android.webkit.JavascriptInterface import android.webkit.WebChromeClient import android.webkit.WebStorage import android.webkit.WebView import android.webkit.WebViewClient import android.widget.TextView import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat //网页支付加载页 class WebPayActivity : AppCompatActivity() { companion object { //获取跳转此页面intent fun getIntent(context: Context, url: String, title: String? = null): Intent { return Intent(context, WebPayActivity::class.java).apply { putExtra("url", url) putExtra("title", title) } } } //屏幕密度 private var density = 0f //缩放屏幕密度 private var scaledDensity = 0f private val ua by lazy { intent.getStringExtra("ua") } private val url by lazy { intent.getStringExtra("url") } private val title by lazy { intent.getStringExtra("title") } private val ivClose by lazy { findViewById(R.id.iv_close) } private val tvTitle by lazy { findViewById(R.id.tv_title) } private val webView by lazy { findViewById(R.id.web) } override fun onCreate(savedInstanceState: Bundle?) { setCustomDensity(this, application) super.onCreate(savedInstanceState) val transparentStyle = SystemBarStyle.light( scrim = Color.TRANSPARENT, // 浅色主题下 scrim darkScrim = Color.TRANSPARENT // 深色主题下 scrim ) enableEdgeToEdge(statusBarStyle = transparentStyle, navigationBarStyle = transparentStyle) setContentView(R.layout.activity_web) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } ivClose.setOnClickListener { finish() } clearWebViewCache() initWebView() } //设置自定义的屏幕密度,解决屏幕适配问题 private fun setCustomDensity(activity: Activity, application: Application) { val displayMetrics = application.resources.displayMetrics if (density == 0f) { density = displayMetrics.density scaledDensity = displayMetrics.scaledDensity application.registerComponentCallbacks(object : ComponentCallbacks { override fun onConfigurationChanged(newConfig: Configuration) { if (newConfig.fontScale > 0) { scaledDensity = application.resources.displayMetrics.scaledDensity } } @Deprecated("Deprecated in Java") override fun onLowMemory() { } }) } val targetDensity: Float = displayMetrics.widthPixels / 375f val targetScaledDensity = targetDensity * (scaledDensity / density) val targetDensityDpi = (160 * targetDensity).toInt() displayMetrics.density = targetDensity displayMetrics.scaledDensity = targetScaledDensity displayMetrics.densityDpi = targetDensityDpi val activityDisplayMetrics = activity.resources.displayMetrics activityDisplayMetrics.density = targetDensity activityDisplayMetrics.scaledDensity = targetScaledDensity activityDisplayMetrics.densityDpi = targetDensityDpi } private fun clearWebViewCache() { // 1. 清除资源缓存(HTML、JS、CSS、图片等) webView.clearCache(true) // 2. 清除 DOM 存储(localStorage / sessionStorage) // 注意:必须在主线程调用,且 WebView 的 settings 中已开启 domStorageEnabled WebStorage.getInstance().deleteAllData() // 3. 清除 IndexedDB / Web SQL Database(如果 H5 使用了) deleteDatabase("webview.db") deleteDatabase("webviewCache.db") // 4. 清除历史记录(非必需,但可以避免回退到旧页面) webView.clearHistory() // 5. 可选:清除 Cookie CookieManager.getInstance().removeAllCookies(null) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CookieManager.getInstance().flush() } } private fun initWebView() { val cookieManager = CookieManager.getInstance() // 1. 允许 WebView 接受 Cookie(默认其实是 true,但显式声明更安全) cookieManager.setAcceptCookie(true) // 2. 允许第三方 Cookie —— 这是关键! if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.setAcceptThirdPartyCookies(webView, true) } // 3. WebSettings 关键开关 webView.settings.apply { javaScriptEnabled = true //允许js调用 domStorageEnabled = true //部分 H5 框架把状态存在 DOM Storage databaseEnabled = true allowContentAccess = true //是否允许在WebView中访问内容URL(Content Url),默认允许 setSupportZoom(true) //支持缩放,默认为true。是下面那个的前提。 builtInZoomControls = true //设置内置的缩放控件。若为false,则该WebView不可缩放 displayZoomControls = false //隐藏原生的缩放控件 javaScriptCanOpenWindowsAutomatically = true //支持通过JS打开新窗口 loadsImagesAutomatically = true //支持自动加载图片 defaultTextEncodingName = "utf-8" //设置编码格式 userAgentString = "$userAgentString webchatPay/wx074c1f0cf5a0ecf4 InAppPay Vzan/miniAppPayment vzanApp navigator.userAgent zhiboApp FullScreen" } webView.addJavascriptInterface(this, "android") webView.webChromeClient = object : WebChromeClient() { override fun onReceivedTitle(view: WebView?, title: String?) { super.onReceivedTitle(view, title) tvTitle.text = title?.ifEmpty { this@WebPayActivity.title } ?: "" } } webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) val cookieManager = CookieManager.getInstance() // 获取该域名下的所有 Cookie val cookies = cookieManager.getCookie(url) Log.d("xxx", "URL: $url") Log.d("xxx", "Cookies: $cookies") } } url?.also { webView.loadUrl(it) } } /** * 跳转小程序支付 */ @JavascriptInterface fun jumpToMiniProgramPay(json: String) { runOnUiThread { Log.d("xxx", json) BusinessModule.webPayCallback?.invokeAndKeepAlive(json) } } override fun finish() { BusinessModule.webPayCallback = null super.finish() } }