Explorar el Código

添加扫码功能

cc12458 hace 1 mes
padre
commit
26aa39ec22

+ 1 - 0
app/build.gradle.kts

@@ -97,4 +97,5 @@ dependencies {
   implementation(project(":core"))
   implementation(project(":library:browser"))
   implementation(project(":library:device:pulse"))
+  implementation(libs.gson)
 }

+ 33 - 1
app/src/main/java/com/hzliuzhi/applet/container/MainActivity.kt

@@ -1,6 +1,8 @@
 package com.hzliuzhi.applet.container
 
+import android.annotation.SuppressLint
 import android.os.Bundle
+import android.view.KeyEvent
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.LocalActivity
 import androidx.activity.compose.setContent
@@ -11,12 +13,20 @@ import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Modifier
 import androidx.navigation.NavHostController
 import androidx.navigation.compose.rememberNavController
+import com.hzliuzhi.applet.browser.webview.WebViewBridge
 import com.hzliuzhi.applet.container.navigation.Host
+import com.hzliuzhi.applet.container.scanner.ScannerListener
+import com.hzliuzhi.applet.container.scanner.rememberScannerListener
+import com.hzliuzhi.applet.core.shared.Event
+import com.hzliuzhi.applet.core.shared.Payload
+import com.hzliuzhi.applet.core.shared.SharedFlowHub
 import com.hzliuzhi.applet.core.theme.SixTheme
 import com.hzliuzhi.applet.device.pulse.PulseEventHandle
 
 class MainActivity : ComponentActivity() {
   private var navController: NavHostController? = null
+  private var scanner: ScannerListener? = null
+
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     enableEdgeToEdge()
@@ -32,7 +42,29 @@ class MainActivity : ComponentActivity() {
         }
       }
 
-      LocalActivity.current?.also { PulseEventHandle(it, rememberCoroutineScope()) }
+      LocalActivity.current?.also {
+        scanner = rememberScannerListener { result ->
+          val code = result.code
+          code.takeIf { code.isNotEmpty() }?.also {
+            val message = Payload.data(data = result).toEvent()?.let { payload ->
+              WebViewBridge.Message(type = "scan", payload = payload)
+            }?.let { message ->
+              Event<WebViewBridge.Message, String>(
+                type = "${SharedFlowHub.WEBVIEW_BRIDGE_EVENT}:js",
+                payload = message
+              )
+            }?.let { event ->
+              SharedFlowHub.emit(event)
+            }
+          }
+        }
+        PulseEventHandle(it, rememberCoroutineScope())
+      }
     }
   }
+
+  @SuppressLint("RestrictedApi")
+  override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+    return scanner?.dispatchKeyEvent(event)?.takeIf { it } ?: super.dispatchKeyEvent(event)
+  }
 }

+ 7 - 0
app/src/main/java/com/hzliuzhi/applet/container/scanner/ScanResult.kt

@@ -0,0 +1,7 @@
+package com.hzliuzhi.applet.container.scanner
+
+data class ScanResult(
+  val code: String,
+  val state: Int = 0,
+  val type: Int = -1,
+)

+ 40 - 0
app/src/main/java/com/hzliuzhi/applet/container/scanner/ScannerListener.kt

@@ -0,0 +1,40 @@
+package com.hzliuzhi.applet.container.scanner
+
+import android.view.KeyEvent
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+
+class ScannerListener(
+  private val interval: Long = 50L,
+  private val onResult: (ScanResult) -> Unit,
+) {
+  private val scanBuffer = StringBuilder()
+  private var lastInputTime = 0L
+
+  fun dispatchKeyEvent(event: KeyEvent): Boolean {
+    if (event.action == KeyEvent.ACTION_DOWN) {
+      val now = System.currentTimeMillis()
+      if (now - lastInputTime > interval) scanBuffer.clear()
+      lastInputTime = now
+
+      event.unicodeChar.takeUnless { it == 0 }?.toChar()?.also { char ->
+        if (char == '\n' || char == '\r') {
+          val code = scanBuffer.toString()
+          if (code.isNotEmpty()) {
+            onResult(ScanResult(code = code))
+            scanBuffer.clear()
+          }
+          return true;
+        } else {
+          scanBuffer.append(char)
+        }
+      }
+    }
+    return false
+  }
+}
+
+@Composable
+fun rememberScannerListener(onResult: (ScanResult) -> Unit): ScannerListener {
+  return remember { ScannerListener { onResult(it) } }
+}

+ 0 - 78
core/src/main/assets/browser/bridge.js

@@ -1,78 +0,0 @@
-class Bridge extends EventTarget {
-  #analysis(string) {
-    let data = { type: '', payload: null, callbackId: '' };
-    try {
-      data = JSON.parse(string);
-    } catch (e) {
-      console.log('log:bridge:js', `[analysis] 解析消息错误: ${e.message}`);
-    }
-    if (
-      data.payload
-      && typeof data.payload === 'object'
-      && data.payload['__code__'] != null
-      && data.payload['__message__'] != null
-    ) {
-      data.error = { code: data.payload['__code__'], message: data.payload['__message__'] };
-    }
-    return data;
-  }
-
-  #pool = new Map();
-
-  static getInstance() {
-    return Bridge._instance ?? (Bridge._instance = new Bridge());
-  }
-
-  static get Platform() {
-    return window['AndroidBridge'];
-  }
-
-  static get UUID() {
-    return crypto.randomUUID();
-  }
-
-  static pulse(userId) {
-    const { promise, ...resolvers } = Promise.withResolvers();
-    this.getInstance().#postMessage('pulse', { userId }, resolvers);
-    return promise;
-  }
-
-  static print(payload) {
-    const { promise, ...resolvers } = Promise.withResolvers();
-    this.getInstance().#postMessage('print', payload, resolvers);
-    return promise;
-  }
-
-  dispatch(message) {
-    console.log('log:bridge:js', `[dispatch] 接收到消息: ${message}`);
-    const { type, callbackId, payload, error } = this.#analysis(message);
-    if (callbackId) {
-      const { resolve, reject } = this.#pool.get(callbackId) ?? {};
-      if (error) { reject?.(error); } else { resolve?.(payload); }
-      this.#pool.delete(callbackId);
-    } else {
-      let event;
-      if (error) event = new ErrorEvent(type, { error, message: error.message });
-      else event = new CustomEvent(type, { detail: payload });
-      super.dispatchEvent(event);
-    }
-  }
-
-  addEventListener(type, callback, options) {
-    super.addEventListener(type, callback, options);
-    return () => super.removeEventListener(type, callback);
-  }
-
-  #postMessage(type, payload, resolvers) {
-    const callbackId = `${type}:${Bridge.UUID}`;
-    this.#pool.set(callbackId, resolvers);
-    const message = JSON.stringify({ type, payload, callbackId })
-    Bridge.Platform.postMessage(message);
-    console.log('log:bridge:js', `[post] 发送的消息: ${message}`);
-  }
-}
-
-window['Bridge'] = Bridge;
-window['bridge'] = Bridge.getInstance();
-
-window.print = Bridge.print.bind(Bridge);