This is the sixth day of my participation in the August Text Challenge.More challenges in August

1. Unstyle the top of the app

Modify android:theme in the androidmanifest.xml file

android:theme="@style/Theme.AppCompat.Light.NoActionBar"
Copy the code

2. Configure the WebView

2.1. In the layout fileactivity_main.xmlAdd to fileWebView

<WebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Copy the code

2.2. The configurationWebViewattribute

 webView = findViewById<WebView>(R.id.web_view).apply {
            loadUrl("file:///android_asset/dist/index.html") // This line reads H5 pages from assets
// loadUrl("file:/// /${filesdir.path}/web/dist/index.html") // This line reads the H5 page from the local file. The current configuration path: / data/user / 0 / com. Holland. Myapp/package/files

            // Expose the calling method. $app. functionName[method name](arg...)
            addJavascriptInterface(JsInterface(this@MainActivity), "$App")
            settings.apply {
                // Set JS support
                javaScriptEnabled = true
                // Set to support zooming
                setSupportZoom(false)
                // DomStorage is supported
                domStorageEnabled = true
            }
            // Set app to open instead of web
            this.webViewClient = object : WebViewClient() {
                override fun shouldOverrideUrlLoading(view: WebView? , url: String?): Boolean {
                    Log.d("shouldOverrideUrlLoading"."url: $url")
                    if(Uri.parse(url).host ! = HttpUtil.myServerHost) { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent)return true
                    }
                    return false}}// Prints H5 ERR logs
            this.webChromeClient = object : WebChromeClient() {
                override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
                    when (consoleMessage.messageLevel()) {
                        MessageLevel.ERROR -> Log.e("H5", consoleMessage.message()) 
                    }
                    return super.onConsoleMessage(consoleMessage)
                }
            }
        }
Copy the code

2.2.1 Configuring the Calling methodJavascriptInterface

package com.holland.myapp.js_interface

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.webkit.JavascriptInterface
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.holland.myapp.CameraActivity
import com.holland.myapp.common.ActivityResultCode
import com.holland.myapp.util.CameraUtil


class JsInterface(private val activity: Activity) {
    // Use android prompt message
    @JavascriptInterface
    fun onToast(msg: String?) = Toast.makeText(
        activity,
        if (msg == null) "Message empty" else if (msg.isBlank()) "Message empty" else msg,
        Toast.LENGTH_SHORT
    ).show()

    // Take photos using CameraX
    @JavascriptInterface
    fun onCameraX(a) = activity.startActivityForResult(
        Intent(activity, CameraActivity::class.java),
        ActivityResultCode.REQUEST_TAKE_PHOTO_CAMERA_X.ordinal
    )

    // Use Camera to take pictures
    @JavascriptInterface
    fun onCamera(a) =
        // Request camera permissions
        if (CameraActivity.REQUIRED_PERMISSIONS.all {
                ContextCompat.checkSelfPermission(
                    activity, it
                ) == PackageManager.PERMISSION_GRANTED
            }) {
            CameraUtil.openCamera(activity)
        } else {
            ActivityCompat.requestPermissions(
                activity,
                CameraActivity.REQUIRED_PERMISSIONS,
                CameraActivity.REQUEST_CODE_PERMISSIONS
            )
        }
}
Copy the code

2.3. Configure the currentActivityattribute

// Set the return event
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    val jsCall = JsCall(webView) // Customize the callback method
    when (requestCode) {
        ActivityResultCode.REQUEST_TAKE_PHOTO_CAMERA.ordinal -> {
            jsCall.appCallJs(1, CameraUtil.currentPhotoPath)
        }
        else-> {}}}// Set the return key assignment to H5 page
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (webView.canGoBack()) {
            webView.goBack()
            return true
        } else {
            exitProcess(0)}}return super.onKeyDown(keyCode, event)
}
Copy the code

2.3.1 Configuring a custom Callback methodJsCall

package com.holland.myapp.js_interface

import android.annotation.SuppressLint
import android.webkit.WebView

class JsCall(private val webView: WebView) {

    / * * *@paramType 1: method callback type *@paramArgs 2: parameter list */
    @SuppressLint("ObsoleteSdkInt")
    fun appCallJs(type: Int, vararg args: String) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            webView.evaluateJavascript("appCallJs(${composeParameter(type, *args)});".null)}else {
            webView.loadUrl("javascript:appCallJs(${composeParameter(type, *args)});")}}private fun composeParameter(type: Int, vararg args: String): String {
        return if (args.isEmpty()) {
            "'$type'"
        } else {
            return "'$type',${args.map { "'$it'" }.reduce { acc, s -> "$acc,$s"}}"}}}Copy the code

3. Configuring H5 (VUE implementation)

Page 3.1.

<template>
  <div>
    <van-field v-model="toast" center clearable label="Android Tips" placeholder="Please enter prompts.">
      <template #button>
        <van-button size="small" type="primary" @click="onToast(toast)">send</van-button>
      </template>
    </van-field>
    <van-button type="info" @click="onCamera()">Camera Camera interface</van-button>
    <van-button type="info" @click="onCameraX()">CameraX camera interface</van-button>
    <van-button type="info" @click="test()">Test button</van-button>
  </div>
</template>

<script>
// Introduce a way to communicate with Android
import AppInterface from ".. /uitl/AppInterface";

export default {
  name: 'HomePage'.mixins: [AppInterface],
  data() {
    return {
      toast: null,}}}</script>
Copy the code

3.2 Configuring the Communication method with Android

export default {
  methods: {
    onToast(message) {
      if (window.$App) $App.onToast(message)
    },
    onCamera() {
      if (window.$App) $App.onCamera()
    },
    onCameraX() {
      if (window.$App) $App.onCameraX()
    }
  }
}

window.appCallJs = function (type, args0, args1, args2, args3, args4, args5, args6, args7, args8, args9) {
  switch (type) {
    case '1':
      /** * When the photo is taken, the camera returns to the local image path *@param Arg0 Local image path */
      break;
    default:
      if (window.$App) window.$App.onToast('Received parameters:${type}.${args0}.${args1}.${args2}.${args3}.${args4}.${args5}.${args6}.${args7}.${args8}.${args9}`)}}Copy the code

4. Achieve results

4.1. General page

4.1. Use Android Tips

4.2. Use CameraX

4.3. H5 reports an error message