package com.example.basecore.base import android.annotation.SuppressLint import android.app.AlertDialog import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.PixelFormat import android.net.Uri import android.text.TextUtils import android.view.KeyEvent import android.webkit.* import android.widget.FrameLayout import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.example.basecore.BaseActivity import com.example.basecore.R import com.example.basecore.util.Constants import com.example.basecore.util.PermissionUtils import com.example.basecore.widget.TitleLayout import com.example.basecore.widget.X5WebView import com.example.basecore.util.LogUtils import com.example.basecore.util.toast import org.json.JSONException import org.json.JSONObject class WebViewActivity : BaseActivity() { private var url: String? = "" private lateinit var container: FrameLayout private lateinit var titleLayout: TitleLayout override fun getLayoutId() = R.layout.activity_web_common private val mWebView by lazy { X5WebView(this, null) } /** * 相机权限 */ private val code_camera = 50 override fun initData() { //网页中的视频,上屏幕的时候,可能出现闪烁的情况 window.setFormat(PixelFormat.TRANSLUCENT) } @SuppressLint("SetJavaScriptEnabled") override fun initView() { container = findViewById(R.id.container) titleLayout = findViewById(R.id.titleLayout) url = intent.getStringExtra(Constants.webUrl) val title = intent.getStringExtra(Constants.webTitle) titleLayout.setTitle(title) container.addView( mWebView, FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT ) ) initClient(mWebView) val webSetting = mWebView.settings webSetting.saveFormData = false val cachePath = filesDir.absolutePath + "XData" webSetting.databasePath = cachePath webSetting.databaseEnabled = true webSetting.domStorageEnabled = true webSetting.cacheMode = WebSettings.LOAD_DEFAULT webSetting.blockNetworkImage = false webSetting.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW val ua = webSetting.userAgentString //todo ua添加 // /** // * ua 添加 // */ // val sb = StringBuilder() // sb.append(ua).append(" ") // .append("kkgame/").append(getVersionName()).append(" ") // .append("h/").append(getImei()).append(" ") // .append("s/").append("android").append(" ") // .append("vc/").append(getVersionCode()).append(" ") // .append("sv/").append(Build.VERSION.RELEASE).append(" ") // .append("netstatus/").append(getNetworkType()).append(" ") // webSetting.userAgentString = sb.toString() webSetting.javaScriptEnabled = true val js = MyJSInterface(this) //js 调用安卓 mWebView.addJavascriptInterface(js, "JSInterface") if (url != null) mWebView.loadUrl(url!!) else mWebView.loadUrl("about:blank") } private fun initClient(mWebView: X5WebView) { mWebView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { LogUtils.e("override url $url") if (url.startsWith("http:") || url.startsWith("https:")) { view.loadUrl(url) return false } //微信和阿里支付 if (url.startsWith("weixin://")) { return try { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) true } catch (e: Exception) { //防止手机没有安装处理某个 scheme 开头的 url 的APP导致crash val builder: AlertDialog.Builder = AlertDialog.Builder(mContext) builder.setTitle("支付中心") .setMessage("该手机没有安装微信客户端,请安装微信后重新完成支付,或换用支付宝进行支付") .setPositiveButton( "确定" ) { dialogInterface, _ -> dialogInterface.dismiss() } .create().show() true } } else if (url.startsWith("alipays://") || url.startsWith("alipay")) { return try { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) true } catch (e: Exception) { // 启动支付宝失败,换成网页支付 return true } } //拉起三方APP try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) startActivity(intent) } catch (e: java.lang.Exception) { } return true } override fun onPageStarted(p0: WebView?, p1: String?, p2: Bitmap?) { super.onPageStarted(p0, p1, p2) } override fun onPageFinished(view: WebView, url: String) { super.onPageFinished(view, url) } } mWebView.webChromeClient = object : WebChromeClient() { /** * 加载进度条 * 主线程,可直接更新 */ override fun onProgressChanged(webview: WebView?, progress: Int) { LogUtils.e("Progress: $progress") super.onProgressChanged(webview, progress) } /** * Webview 中的标题 */ override fun onReceivedTitle(p0: WebView?, title: String?) { super.onReceivedTitle(p0, title) // titleLayout.setTitle(title) } /** * JS confirm 对话框 */ override fun onJsConfirm( arg0: WebView, arg1: String, arg2: String, arg3: JsResult ): Boolean { return super.onJsConfirm(arg0, arg1, arg2, arg3) } /** * 隐藏全局播放 */ override fun onHideCustomView() { } override fun onJsAlert( arg0: WebView, arg1: String, arg2: String, arg3: JsResult ): Boolean { return super.onJsAlert(null, arg1, arg2, arg3) } override fun onShowFileChooser( webView: WebView?, filePathCallback: ValueCallback>?, fileChooserParams: FileChooserParams? ): Boolean { if (fileChooserParams != null) { LogUtils.e("fileChooserParams: $fileChooserParams") } if (filePathCallback != null) valueCallback = filePathCallback val camera = PermissionUtils.CAMERA if (ContextCompat.checkSelfPermission(mContext, camera) == PackageManager.PERMISSION_DENIED ) { ActivityCompat.requestPermissions( this@WebViewActivity, arrayOf(camera), code_camera ) } else { showAlbum() } return true } // fun openFileChooser( // filePathCallback: ValueCallback?, // p1: String?, // p2: String? // ) { // if (filePathCallback != null) // valueCallback = filePathCallback // // val camera = "android.permission.CAMERA" // if (ContextCompat.checkSelfPermission(mContext, camera) == // PackageManager.PERMISSION_DENIED // ) { // ActivityCompat.requestPermissions( // this@KKWebViewActivity, // arrayOf(camera), // code_camera // ) // } else { // showAlbum() // } // } } } private var valueCallback: ValueCallback>? = null override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == code_camera && grantResults[0] == PackageManager.PERMISSION_GRANTED) { showAlbum() } else { toast("权限不足") } } /** * 打开相机 */ private fun showAlbum() { } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (null == valueCallback) { return } } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { //记录当前页面URL,如果返回还是同样的url,说明有重定向,再返回一次即可 if (url == mWebView.url) { finish() } mWebView.goBack() return true } return super.onKeyDown(keyCode, event) } override fun onPause() { super.onPause() mWebView.onPause() } override fun onResume() { super.onResume() mWebView.onResume() } override fun onDestroy() { super.onDestroy() container.removeAllViews() mWebView.stopLoading() mWebView.clearMatches() mWebView.clearHistory() mWebView.clearSslPreferences() mWebView.clearCache(true) mWebView.loadUrl("about:blank") mWebView.removeAllViews() mWebView.removeJavascriptInterface("javaobj") mWebView.destroy() } inner class MyJSInterface(context: Context) { private var mContext: Context = context @JavascriptInterface fun showWeb(json: String?) { var url: String? = null try { val jsonObject = JSONObject(json) url = jsonObject.optString("url") val intent = Intent(this@WebViewActivity, WebViewActivity::class.java) intent.putExtra(Constants.webUrl, url) mContext.startActivity(intent) // mWebView.loadUrl(url) } catch (e: JSONException) { e.printStackTrace() } if (TextUtils.isEmpty(url)) { toast("未知异常") return } } @JavascriptInterface fun showQQChat(json: String?) { var jsonObject: JSONObject? = null try { jsonObject = JSONObject(json) val key = jsonObject.optString("value") val url = "mqqwpa://im/chat?chat_type=wpa&uin=" //uin是发送过去的qq号码 mContext.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url + key))) } catch (e: JSONException) { e.printStackTrace() mContext.toast("未知异常") } catch (e: java.lang.Exception) { // 未安装手Q或安装的版本不支持 mContext.toast("未安装手Q或安装的版本不支持") } } } }