国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【JoAPP】Android WebView與H5交互實現(xiàn)(JAVA+KOTLIN)

這篇具有很好參考價值的文章主要介紹了【JoAPP】Android WebView與H5交互實現(xiàn)(JAVA+KOTLIN)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1、前言

? ? ? ?最近一個應(yīng)急平臺的項目移動端開發(fā),原計劃用UNI-APP實現(xiàn),客戶想著要集成語音、視頻通話功能,基于經(jīng)驗判斷需要買一套IM原生移動端框架去結(jié)合H5整合比較合適,沒想到最后客戶不想采購,而且語音視頻通話功能也遲遲未能完全確認(rèn),H5部分所開發(fā)的業(yè)務(wù)功能已經(jīng)實現(xiàn),但原生端開發(fā)模式遲遲未定,緊急時刻,決定啟動前幾年一直使用的一組android原生APP+H5(WEB)實現(xiàn)移動端開發(fā),隨即找了前幾年的原生框架代碼,發(fā)現(xiàn)與新的版本已不兼容,索性重新梳理,整理一套新的代碼,也決定對外開放給朋友們使用,暫時延續(xù)之前內(nèi)部框架名稱JoApp,目前只整理了android+h5代碼,后續(xù)還會將IOS版整理出來。

? ? ? ? 恰逢2024年第一天元旦,祝福各位朋友新年快樂!這個節(jié)假日老哥我最大收獲就是這個框架中實現(xiàn)了人臉識別、人臉對比的API,滿足各類應(yīng)用系統(tǒng)手機(jī)APP中實現(xiàn)人臉識別、位置校驗的需要,方便大家哪里即用。

本文涉及代碼開發(fā)工具如下:

Android Studio Giraffe | 2022.3.1 Patch 3、VSCode

語言及管理:

Java Jdk(OpenJDK17)、Kotlin、Gradle-8.4

2、原生APP與H5交互的核心實現(xiàn)

? ? ? ?基于JS方法在在APP與WebView內(nèi)的H5間進(jìn)行調(diào)用實現(xiàn),這里主要演示Kotilin的代碼,如需要JAVA版,可以使用文心一言等智能工具進(jìn)行轉(zhuǎn)換。

? ? ? ?原生APP端核心原理代碼如下(寫在 MainActivity內(nèi)):

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 隱藏狀態(tài)欄和導(dǎo)航欄
        requestWindowFeature(Window.FEATURE_NO_TITLE)

        // 設(shè)置窗口全屏
        window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        )


        // 獲取 WebView 組件
        webview = findViewById<WebView>(R.id.web_view)

        // 獲取并設(shè)置 Web 設(shè)置
        val settings = webview?.settings
        settings?.javaScriptEnabled = true   // 支持 JavaScript
        // 設(shè)置是否啟用 DOM 存儲
        // DOM 存儲是一種在 Web 應(yīng)用程序中存儲數(shù)據(jù)的機(jī)制,它使用 JavaScript 對象和屬性來存儲和檢索數(shù)據(jù)
        settings?.domStorageEnabled = true
        // 設(shè)置 WebView 是否啟用內(nèi)置縮放控件 ( 自選 非必要 )
        //settings.builtInZoomControls = true

        // 5.0 以上需要設(shè)置允許 http 和 https 混合加載
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        } else {
            // 5.0 以下不用考慮  http 和 https 混合加載 問題
            settings?.mixedContentMode = WebSettings.LOAD_NORMAL
        }

        // 設(shè)置頁面自適應(yīng)
        // Viewport 元標(biāo)記是指在 HTML 頁面中的 <meta> 標(biāo)簽 , 可以設(shè)置網(wǎng)頁在移動端設(shè)備上的顯示方式和縮放比例
        // 設(shè)置是否支持 Viewport 元標(biāo)記的寬度
        settings?.useWideViewPort = true

        // 設(shè)置 WebView 是否使用寬視圖端口模式
        // 寬視圖端口模式下 , WebView 會將頁面縮小到適應(yīng)屏幕的寬度
        // 沒有經(jīng)過移動端適配的網(wǎng)頁 , 不要啟用該設(shè)置
        settings?.loadWithOverviewMode = true

        // 設(shè)置 WebView 是否可以獲取焦點 ( 自選 非必要 )
        webview?.isFocusable = true
        // 設(shè)置 WebView 是否啟用繪圖緩存 位圖緩存可加速繪圖過程 ( 自選 非必要 )
        webview?.isDrawingCacheEnabled = true
        // 設(shè)置 WebView 中的滾動條樣式 ( 自選 非必要 )
        // SCROLLBARS_INSIDE_OVERLAY - 在內(nèi)容上覆蓋滾動條 ( 默認(rèn) )
        webview?.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY

        // WebViewClient 是一個用于處理 WebView 頁面加載事件的類
        webview?.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                // 4.0 之后必須添加該設(shè)置
                // 只能加載 http:// 和 https:// 頁面 , 不能加載其它協(xié)議鏈接
                if (url.startsWith("http://") || url.startsWith("https://")) {
                    view.loadUrl(url)
                    return true
                }
                return false
            }

            // SSL 證書校驗出現(xiàn)異常
            override fun onReceivedSslError(
                view: WebView,
                handler: SslErrorHandler,
                error: SslError
            ) {
                when (error.primaryError) {
                    SslError.SSL_INVALID, SslError.SSL_UNTRUSTED -> {
                        handler.proceed()
                    }
                    else -> handler.cancel()
                }
            }

        }

        // WebChromeClient 是一個用于處理 WebView 界面交互事件的類
        webview?.webChromeClient =  MyWebChromeClient()
        // 加載網(wǎng)頁
        webview?.loadUrl(WebUrl)

        // js調(diào)用安卓方法支持(第二個參數(shù)是js代碼中調(diào)用APP中的交互橋類定義的名,需保持一致)
        webview?.addJavascriptInterface(JoAppObject(),"joApp")
        
        // 原生調(diào)用js中的方法(不帶參數(shù)版) 
        // 這里joAppJs與H5 web端中定義的被原生調(diào)用JS類new的變量名一致,方便統(tǒng)一調(diào)用
        joAppJs("joAppJs.test")
        // 原生調(diào)用js中的方法(帶參數(shù)版)
        joAppJs("joAppJs.testData","一只可愛的對號")

    }


    // 原生調(diào)用JS方法,方法名
    fun joAppJs(funName: String){
        JoDebug.show(this@MainActivity,  " - " + funName, Toast.LENGTH_LONG)
        if (Build.VERSION.SDK_INT< 18) {
          webview?.loadUrl("javascript:$funName()")

        } else {
            // 安卓調(diào)用js方法 4.4以上
            webview?.evaluateJavascript(
                "javascript:$funName()",
                object : ValueCallback<String> {
                    override fun onReceiveValue(res: String?) {
                        //此處為 js 返回的結(jié)果
                        //System.out.print(res)
                        //return res
                    }
                })
        }
    }
    // 原生調(diào)用JS方法,參數(shù)1:JS方法名、參數(shù)2:傳給JS方法的參數(shù)(支持json字符串)
    fun joAppJs(funName: String, data: String){
        // 舊版android支持
        if (Build.VERSION.SDK_INT< 18) {
            if(data==null) {
                webview?.loadUrl("javascript:$funName()")
            }else{
                webview?.loadUrl("javascript:$funName('$data')")
            }
        } else {
            // 安卓調(diào)用js方法 4.4以上
            if(data==null) {
                webview?.evaluateJavascript(
                    "javascript:$funName()",
                    object : ValueCallback<String> {
                        override fun onReceiveValue(res: String?) {
                            //此處為 js 返回的結(jié)果
                            //System.out.print(res)
                            //return res
                        }
                    })
            }else{
                webview?.evaluateJavascript("javascript:$funName('$data')", object : ValueCallback<String> {
                    override fun onReceiveValue(res: String?) {
                        //此處為 js 返回的結(jié)果
                        //System.out.print(res)
                        //return res
                    }
                })
            }

        }
    }


    /*
    * JoApp 原生提供給H5可被JS調(diào)用的橋類庫,真實的原生實現(xiàn)方法類庫
      需要將與原生交互的各種API類寫在這里,實現(xiàn)H5的方便調(diào)用
    * */
    inner  class JoAppObject {

        //測試jsAndroid調(diào)用
        @JavascriptInterface
        fun jsAndroid(msg: String) {
            //點擊html的Button調(diào)用Android的Toast代碼
            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, msg, Toast.LENGTH_LONG)
        }
    }

? ? ? ? 嵌入的H5 WEB中配套代碼如下:

...

<button type="button" onclick="clickAndroid()">無回傳調(diào)用安卓方法</button>

...

 <script type="text/javascript">

     /*
    JoAppJs 安卓調(diào)用的JS方法庫
    */
    class JoAppJs {
        //測試不帶參數(shù)
        test () {
            alert("Android調(diào)用了JS代碼")
            document.getElementById("showres").innerHTML = "Android調(diào)用了JS代碼"
        }
        //測試不帶參數(shù)
        testData (data) {
             alert("Android調(diào)用了JS代碼" + data) 
             document.getElementById("showres").innerHTML = data
        }

        
    }

    //定義被APP原生調(diào)用的H5中JS類庫變量名,方便統(tǒng)一調(diào)用
    const joAppJs = new JoAppJs()


    //測試調(diào)用原生APP
    function clickAndroid(){
        //用joapp.調(diào)用映射的對象    這里的androids是addJavascriptInterface()的第二個參數(shù)
        joApp.jsAndroid("我是JS,我調(diào)用了Android的方法")
    }
    
</script>

3、JoAPP已實現(xiàn)的交互API方法庫

? ? ? ?在JoApp中已經(jīng)實現(xiàn)了一些原生APP與WebView H5中js的交互方法,以下列出當(dāng)前關(guān)鍵方法,后續(xù)會逐步新增在JoApp Git倉庫中,也會在后續(xù)文章中逐個解析重點API實現(xiàn)原理。

? ? ? ? APP已實現(xiàn)的API包括:

  • 配置信息:joConfig
  • APP接收WEB中token:joToen
  • 向WEB發(fā)送APP中token:joTokenToWeb
  • 啟動原生文件上傳:joFile
  • 啟動原生圖片上傳(瀏覽相冊+拍照):joImage
  • 獲取原生APP位置信息(經(jīng)緯度):joLocation
  • APP接收位置有效性檢測參照信息:joCheckLocation
  • APP接收人臉有效性檢測參照信息:joCheckFace
  • 啟動APP人臉及位置有效性對比功能:joFaceCompare
  • 啟動APP設(shè)置界面(配置WEB網(wǎng)址):joSetting

? ? ? ? 具體代碼如下,請根據(jù)需要自行依據(jù)注釋進(jìn)行使用:



    //權(quán)限
    var permissions = arrayOf(
        Manifest.permission.READ_PHONE_STATE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS,
        Manifest.permission.ACCESS_NETWORK_STATE,
        Manifest.permission.ACCESS_WIFI_STATE,
        Manifest.permission.SYSTEM_ALERT_WINDOW,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.CHANGE_WIFI_STATE,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
        Manifest.permission.CHANGE_NETWORK_STATE,
        Manifest.permission.GET_TASKS,
        Manifest.permission.VIBRATE,
        Manifest.permission.CAMERA,
    )
    private fun initPermission() {
        MPermissionUtils.requestPermissionsResult(
            this@MainActivity,
            1,
            permissions,
            object : MPermissionUtils.OnPermissionListener {
                override fun onPermissionGranted() {}
                override fun onPermissionDenied() {
                    MPermissionUtils.showTipsDialog(this@MainActivity)
                }
            })
    }



    // 加載完成后自動調(diào)取的js
    fun onLoagJs() {

        //joAppJs("joAppJs.test")
        //joAppJs("joAppJs.testData","我的神")

        //獲取H5中包括接口地址在內(nèi)的設(shè)置等信息,用于傳遞H5中的默認(rèn)信息給原生app
        //改由web頁面加載后向原生單向推送
        //joAppJs("joAppJs.config")

        //向web傳入app緩存中的token
        //改由web頁面加載后向原生推送
        //joAppJs("joAppJs.token");

    }

    // 調(diào)用JS方法, 方法名、參數(shù)(支持json字符串)
    fun joAppJs(funName: String){
        JoDebug.show(this@MainActivity,  " - " + funName, Toast.LENGTH_LONG)
        if (Build.VERSION.SDK_INT< 18) {
          webview?.loadUrl("javascript:$funName()")

        } else {
            // 安卓調(diào)用js方法 4.4以上
            webview?.evaluateJavascript(
                "javascript:$funName()",
                object : ValueCallback<String> {
                    override fun onReceiveValue(res: String?) {
                        //此處為 js 返回的結(jié)果
                        //System.out.print(res)
                        //return res
                    }
                })
        }
    }
    fun joAppJs(funName: String, data: String){
        if (Build.VERSION.SDK_INT< 18) {
            if(data==null) {
                webview?.loadUrl("javascript:$funName()")
            }else{
                webview?.loadUrl("javascript:$funName('$data')")
            }
        } else {
            // 安卓調(diào)用js方法 4.4以上
            if(data==null) {
                webview?.evaluateJavascript(
                    "javascript:$funName()",
                    object : ValueCallback<String> {
                        override fun onReceiveValue(res: String?) {
                            //此處為 js 返回的結(jié)果
                            //System.out.print(res)
                            //return res
                        }
                    })
            }else{
                webview?.evaluateJavascript("javascript:$funName('$data')", object : ValueCallback<String> {
                    override fun onReceiveValue(res: String?) {
                        //此處為 js 返回的結(jié)果
                        //System.out.print(res)
                        //return res
                    }
                })
            }

        }
    }



    //跳轉(zhuǎn)到下一個頁面
    fun OpenSetting() {
        val intent = Intent(this, SettingActivity::class.java)
        startActivity(intent)
        finish()
    }

    //啟動人臉對比窗口
    fun onFaceStart() {
        val intent = Intent();
        //intent.setClass(this@MainActivity, FaceCheckActivity::class.java)
        intent.setClass(this@MainActivity, FaceCompareActivity::class.java)
        startActivity(intent)
    }

    // 接收文件選擇器回傳信息
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            FilePickerManager.REQUEST_CODE -> {
                if (resultCode == Activity.RESULT_OK) {

                    // 收到選擇文件列表
                    val list = FilePickerManager.obtainData()
                    // 執(zhí)行上傳等工作
                    Toast.makeText(this@MainActivity, "你選擇了文件數(shù)" + list.size, Toast.LENGTH_SHORT).show()

                } else {
                    Toast.makeText(this@MainActivity, "你未執(zhí)行任何選擇", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }


    /*
    * JoApp JS調(diào)用原生橋類庫
    * */
    inner  class JoAppObject {

        //測試jsAndroid調(diào)用
        @JavascriptInterface
        fun jsAndroid(msg: String) {
            //點擊html的Button調(diào)用Android的Toast代碼
            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, msg, Toast.LENGTH_LONG)
        }

        //接收js傳回的web端配置,統(tǒng)一app端原生與嵌套H5的接口
        @JavascriptInterface
        fun joConfig(config: String) {
            //解析json字符串
            val jsonObject = JSONObject(config)
            val joApiUrl: String = jsonObject.getString("ApiUrl")
            val joAppTitle: String = jsonObject.getString("AppTitle")
            val joUpBucketName: String = jsonObject.getString("UpBucketName")
            val joUpFileName: String = jsonObject.getString("UpFileName")
            val joAuthorization: String = jsonObject.getString("Authorization")
            IsDebug = jsonObject.getString("IsDebug")
            PreferencesUtils.putString(this@MainActivity, "IsDebug", IsDebug)
            ApiUrl = joApiUrl
            PreferencesUtils.putString(this@MainActivity, "ApiUrl", ApiUrl)
            FileUpApi= ApiUrl + "common/upload"; //文件上傳接口
            PreferencesUtils.putString(this@MainActivity, "FileUpApi", FileUpApi)
            ImageUpApi= ApiUrl + "common/upload"; //圖片上傳接口
            PreferencesUtils.putString(this@MainActivity, "ImageUpApi", ImageUpApi)
            VideoUpApi= ApiUrl + "common/upload"; //視頻上傳接口
            PreferencesUtils.putString(this@MainActivity, "VideoUpApi", VideoUpApi)
            Authorization = joAuthorization
            PreferencesUtils.putString(this@MainActivity, "Authorization", Authorization)

            Applicationcode = jsonObject.getString("Applicationcode")
            PreferencesUtils.putString(this@MainActivity, "Applicationcode", Applicationcode)
            ApplicationcodeValue = jsonObject.getString("ApplicationcodeValue")
            PreferencesUtils.putString(this@MainActivity, "ApplicationcodeValue", ApplicationcodeValue)

            AppTitle = joAppTitle
            PreferencesUtils.putString(this@MainActivity, "AppTitle", AppTitle)
            UpBucketName = joUpBucketName; //上傳默認(rèn)盒
            PreferencesUtils.putString(this@MainActivity, "UpBucketName", UpBucketName)
            UpFileName = joUpFileName;  //上傳模擬文件字段名
            PreferencesUtils.putString(this@MainActivity, "UpFileName", UpFileName)

            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, ApiUrl + " - " + joAppTitle, Toast.LENGTH_LONG)
        }

        //接收js傳回的web端token,統(tǒng)一app端原生與嵌套H5的token驗證
        @JavascriptInterface
        fun joToken(token: String) {
            JoDebug.show(this@MainActivity,  " Token1 - " + Token, Toast.LENGTH_LONG)
            // 存儲token
            PreferencesUtils.putString(this@MainActivity, "token", token)

            //解析json字符串
            Token = PreferencesUtils.getString(this@MainActivity, "token");
            JoDebug.show(this@MainActivity,  " Token - " + Token, Toast.LENGTH_LONG)
        }

        //將APP中token傳入web,實現(xiàn)web根據(jù)app存儲的token自動登錄
        @JavascriptInterface
        fun joTokenToWeb() {
            Token = PreferencesUtils.getString(this@MainActivity, "token");
            joAppJs("joAppJs.setToken", Token);
        }

        //文件選擇、上傳
        @JavascriptInterface
        fun joFile(returnFunName: String, data: String) {
            //點擊html的Button調(diào)用Android的Toast代碼
            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, returnFunName + " - " + data, Toast.LENGTH_LONG)
            //調(diào)用上傳方法
            //JoFile.joFile(this@MainActivity, webview, returnFunName, data)
        }

        //圖片選擇、上傳
        @JavascriptInterface
        fun joImage(returnFunName: String, data: String) {
            //點擊html的Button調(diào)用Android的Toast代碼
            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, returnFunName + " - " + data, Toast.LENGTH_LONG)
            //調(diào)用上傳方法
            JoImage.joImage(this@MainActivity, webview, returnFunName, data)
        }

        //位置信息獲取經(jīng)緯度
        @JavascriptInterface
        fun joLocation(returnFunName: String, data: String) {
            JoDebug.show(this@MainActivity, returnFunName + " - " + data, Toast.LENGTH_LONG)
            //調(diào)用位置獲取方法
            JoLocation.LatLng(this@MainActivity, webview, returnFunName, data)
        }

        //寫入位置范圍檢測信息,參照點位經(jīng)度、維度、距離
        @JavascriptInterface
        fun joCheckLocation(data: String) {
            // 存儲token
            PreferencesUtils.putString(this@MainActivity, "CheckLocation", data)
        }

        //寫入人臉比對校驗信息,參照人臉URL,姓名,達(dá)標(biāo)相似度
        @JavascriptInterface
        fun joCheckFace(data: String) {
            // 存儲token
            PreferencesUtils.putString(this@MainActivity, "CheckFace", data)
        }

        //人臉信息對比
        @JavascriptInterface
        fun joFaceCompare(returnFunName: String, data: String) {
            JoDebug.show(this@MainActivity, returnFunName + " - " + data, Toast.LENGTH_LONG)
            //人臉對比獲取方法
            onFaceStart();
        }

        //打開本地人臉庫
        @JavascriptInterface
        fun joFaceData() {
            //JoDebug.show(this@MainActivity, returnFunName + " - " + data, Toast.LENGTH_LONG)
            //人臉對比獲取方法
            val intent = Intent();
            intent.setClass(this@MainActivity, SearchNaviActivity::class.java)
            startActivity(intent)

        }


        //打開APP設(shè)置界面
        @JavascriptInterface
        fun joSetting() {
            OpenSetting()
        }


        @JavascriptInterface
        fun jsAndroidRes(msg: String, resJsFun: String) {

            //this@MainActivity.webview?.loadUrl("javascript:$resJsFun()")

            //回傳數(shù)據(jù)給js //, "數(shù)據(jù)回來啦!"
            JoDebug.show(this@MainActivity,  " - " + resJsFun, Toast.LENGTH_LONG)


            //點擊html的Button調(diào)用Android的Toast代碼
            //我這里讓Toast居中顯示了
            JoDebug.show(this@MainActivity, msg + " - " + resJsFun, Toast.LENGTH_LONG)

        }

    }

    // 重定義web彈窗
    inner class MyWebChromeClient:WebChromeClient(){

        // 顯示 網(wǎng)頁加載 進(jìn)度條
        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            Log.d("JoApp","${newProgress}")
            super.onProgressChanged(view, newProgress)

            if (newProgress == 100) {
                //加載100%
                Log.d(TAG, "onProgressChanged: " + "webView---100%");

                //執(zhí)行加載完成調(diào)用js,如:傳入token等
                onLoagJs()
//                if (!isWebViewloadError && View.VISIBLE == btnRetry.getVisibility()){
//                    btnRetry.setVisibility(View.GONE);//重新加載按鈕
//                }
            }
        }

        // 處理 WebView 對地理位置權(quán)限的請求
        override fun onGeolocationPermissionsShowPrompt(
            origin: String,
            callback: GeolocationPermissions.Callback) {
            super.onGeolocationPermissionsShowPrompt(origin, callback)
            callback.invoke(origin, true, false)
        }
        override fun onJsAlert(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("JoApp","$message + $result")
            return super.onJsAlert(view, url, message, result)
        }

        override fun onJsPrompt(
            view: WebView?,
            url: String?,
            message: String?,
            defaultValue: String?,
            result: JsPromptResult?
        ): Boolean {
            Log.d("JoApp","$message + $result")
            return super.onJsPrompt(view, url, message, defaultValue, result)
        }

        override fun onJsConfirm(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("JoApp","$message + $result")
            return super.onJsConfirm(view, url, message, result)
        }

        override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
            Log.d("JoApp","${consoleMessage?.message()}")
            return super.onConsoleMessage(consoleMessage)
        }

        lateinit var webkitPermissionRequest: PermissionRequest

        override fun onPermissionRequest(request: PermissionRequest) {
            webkitPermissionRequest = request
            val requestedResources = request.resources
            for (r in requestedResources) {
                if (r == PermissionRequest.RESOURCE_VIDEO_CAPTURE) {
                    request.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
                    break
                }
            }
        }


    }


    /*
    * 監(jiān)聽窗體間信息傳遞
    * */
    inner class MyBroadcastReceive : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            Log.e(TAG,"開始接收.....");
            val result = intent.getStringExtra("result")
            val data = intent.getStringExtra("data")

            if (result != null) {
                Log.e(TAG,"result:" + result);
                val jsonData = "{\"code\":\"200\",\"data\":\"$data\"}"

                //人臉檢測結(jié)果返回
                if (result == "compareFace") {
                    JoPushWeb(
                        jsonData,
                        "joAppJs.compareFace",
                        webview
                    )
                }

                //打開設(shè)置窗口
                if (result == "openSetting") {
                    OpenSetting()
                }

                //保存設(shè)置
                if (result == "saveSetting") {
                    webViewReload()
                }


                //打開進(jìn)度條
                if (result == "progressBar" || result === "progressBar") {
                    val progressBar: ProgressBar = findViewById<ProgressBar>(R.id.progressBar)
                    val pre = data!!.toInt()
                    if (pre >= 100) { //關(guān)閉
                        progressBar.visibility = View.GONE
                    } else {
                        progressBar.visibility = View.VISIBLE
                        progressBar.progress = data.toInt()
                    }
                }


//                Log.e(MainActivity.TAG, result)
            }
        }
    }

4、結(jié)尾

? ? ? ?一定要趕在新年第一天內(nèi)完成本篇發(fā)布,更加詳細(xì)代碼本文暫不作詳細(xì)講解。后續(xù)將持續(xù)發(fā)文講解,并將代碼放到這里。本人安卓水平優(yōu)先,文章適用于眾多新手,老手可直接繞過?。?!

????????所有代碼免費分享給大家隨便使用,無需考慮版權(quán)和收費問題,完整代碼放在下面的連接中了,請拿走。

joapp: 一個用于原生APP與內(nèi)嵌WEB間進(jìn)行交互的代碼集合,方便實現(xiàn)H5中對原生APP各種能力的調(diào)用,簡單易用。 (gitee.com)

????????附代碼結(jié)構(gòu)截圖:

【JoAPP】Android WebView與H5交互實現(xiàn)(JAVA+KOTLIN),JoAPP代碼解析,Android+WEB混合開發(fā)實戰(zhàn),android文章來源地址http://www.zghlxwxcb.cn/news/detail-777695.html

到了這里,關(guān)于【JoAPP】Android WebView與H5交互實現(xiàn)(JAVA+KOTLIN)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • uniapp webview交互以及h5傳參到app

    app端,onPostMessage在nvue頁面下接受參數(shù),message在vue頁面下接受參數(shù) 鏈接后拼接傳參,只在一開始能傳 方法傳參 H5端,我這是用vue2寫的 在index.html頁面加上這個 在首頁接受參數(shù) 往APP傳參 接受APP的方法傳參,變量跟data里面的變量綁定

    2024年02月16日
    瀏覽(29)
  • uniapp app的webview與h5交互操作

    uniapp app的webview與h5交互操作

    app里的webview與h5交互操作,需要在h5頁面加點代碼,然后才能執(zhí)行app里的方法 官方地址 在nvue頁面里才能實現(xiàn)與h5的交互,設(shè)置webview的高度

    2024年02月11日
    瀏覽(23)
  • uniapp webview h5和app交互通信傳參

    app端,onPostMessage在nvue頁面下接受參數(shù),message在vue頁面下接受參數(shù) 鏈接后拼接傳參,只在一開始能傳 方法傳參 H5端,我這是用vue2寫的 在index.html頁面加上這個 在首頁接受參數(shù) 往APP傳參 接受APP的方法傳參,變量跟data里面的變量綁定

    2024年02月15日
    瀏覽(16)
  • Android WebView H5視頻播放實現(xiàn)全屏播放功能、全屏按鈕不顯示、灰顯、點擊無效問題解決方案

    打開硬件加速(3.0以上版本支持) set一個WebChromClient,實現(xiàn)onShowCustomView() 方法和onHideCustomView()方法 全屏支持 打開硬件加速 在Manifest中,對應(yīng)的Activity添加: android:hardwareAccelerated = “true”。 防止h5重新加載:Manifest中,對應(yīng)的Activity添加: android:configChanges=“keyboardHidden|orientation|s

    2024年02月09日
    瀏覽(27)
  • 使用JSBridge框架來實現(xiàn)Android與H5(JS)交互

    1.首先我們來了解一下什么是JSBridge? 在開發(fā)中,為了追求開發(fā)的效率以及移植的便利性,一些展示性強的頁面我們會偏向于使用h5來完成,功能性強的頁面我們會偏向于使用native來完成,而一旦使用了h5,為了在h5中盡可能的得到native的體驗,我們native層需要暴露一些方法給

    2024年02月08日
    瀏覽(20)
  • Vue.js uni-app 混合模式原生App webview與H5的交互

    Vue.js uni-app 混合模式原生App webview與H5的交互

    在現(xiàn)代移動應(yīng)用開發(fā)中,原生App與H5頁面之間的交互已經(jīng)成為一個常見的需求。本文將介紹如何在Vue.js框架中實現(xiàn)原生App與H5頁面之間的數(shù)據(jù)傳遞和方法調(diào)用。我們將通過一個簡單的示例來展示如何實現(xiàn)這一功能。 效果圖如下: 首先,我們需要在Vue.js項目中引入原生App與H5頁面

    2024年02月16日
    瀏覽(22)
  • Java搭配H5實現(xiàn)前后端交互評論功能

    前言 : ? ? ? ? 最近有個朋友有償讓我?guī)退麄儗⑦@個評論組件整合到他們的靜態(tài)網(wǎng)頁當(dāng)中,并實現(xiàn)數(shù)據(jù)持久化。后來他覺得太麻煩,就放棄了。盡管沒有拿到相應(yīng)的報酬,但只是花了短短的時間寫完了這個簡單功能,并有機(jī)會將其分享給大家。內(nèi)容不長,全是干貨,請擇需

    2024年04月16日
    瀏覽(16)
  • Android實戰(zhàn)基礎(chǔ) - Java、Kotlin 代碼互轉(zhuǎn)

    Android實戰(zhàn)基礎(chǔ) - Java、Kotlin 代碼互轉(zhuǎn)

    在Android現(xiàn)階段,Kotlin已經(jīng)成為普遍性使用的語言,而在其使用階段中Java和Kotlin的混用很常見,為了便于開發(fā),我們需要掌握J(rèn)ava、Kotlin文件的轉(zhuǎn)換 這應(yīng)該是我以前剛學(xué)Kotlin時就想記錄的一篇blog,沒想到隔了這么久才進(jìn)行記錄(嗯… 主要這倆年好像有點忙…) 個人建議:正常

    2024年02月11日
    瀏覽(22)
  • Android WebView:這是一份 詳細(xì) & 易懂的WebView學(xué)習(xí)攻略(含與JS交互

    Android WebView:這是一份 詳細(xì) & 易懂的WebView學(xué)習(xí)攻略(含與JS交互

    Webview 的使用主要包括: Webview 類 及其 工具類( WebSettings 類、 WebViewClient 類、 WebChromeClient 類) 下面我將詳細(xì)介紹上述4個使用類 使用方法 具體請看文章:Android開發(fā):最全面、最易懂的Webview詳解 在 Android WebView 的使用中,與前端 h5 頁面交互的需求十分常見 Android 與 JS 通過

    2024年04月10日
    瀏覽(66)
  • Android中使用WebView與JS交互全解析

    Android中使用WebView與JS交互全解析

    首先,需要提出一個概念,那就是hybrid,主要意思就是native原生Android和h5混合開發(fā)。為什么要這樣做呢?大家可以想象一下針對于同一個活動,如果使用純native的開發(fā)方式,Android和iOS兩邊都要維護(hù)同一套界面甚至是邏輯,這樣開發(fā)和維護(hù)的成本會很大,而使用hybrid的開發(fā)方式

    2024年04月09日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包