From dc30881d38d4ca731e1b50e78c84450611708d55 Mon Sep 17 00:00:00 2001 From: leon <916117771@qq.com> Date: Mon, 13 Apr 2026 16:03:06 +0800 Subject: [PATCH] 1 --- .../java/com/xiarui/zhiwen/ZhiwenPlugin.java | 101 +++++++++++++++--- lib/zhiwen.dart | 7 ++ lib/zhiwen_method_channel.dart | 17 +++ lib/zhiwen_platform_interface.dart | 6 ++ 4 files changed, 115 insertions(+), 16 deletions(-) diff --git a/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java b/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java index c67f95b..ad96699 100644 --- a/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java +++ b/android/src/main/java/com/xiarui/zhiwen/ZhiwenPlugin.java @@ -15,6 +15,7 @@ import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.EventChannel; import android.os.SystemClock; @@ -32,18 +33,23 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA // 常量定义 private static final String TAG = "ZhiwenPlugin"; private static final String CHANNEL_NAME = "zhiwen"; + private static final String EVENT_CHANNEL_NAME = "zhiwen_progress"; private static final int DEFAULT_MAX_FP_COUNT = 3000; private static final int ENROLL_STEP_COUNT = 3; private static final int IMAGE_BUFFER_SIZE = 1024 * 100; - + // 响应状态码 private static final int RESPONSE_SUCCESS = 1; private static final int RESPONSE_FAIL = -1; private static final int RESPONSE_NOT_FOUND = 0; - + /// Flutter与Android原生通信的MethodChannel /// 用于注册插件到Flutter引擎,并在Activity分离时注销 private MethodChannel channel; + + /// 进度事件通道,用于向Flutter发送指纹录入进度 + private EventChannel progressEventChannel; + private EventChannel.EventSink progressEventSink; // 设备通信对象,使用static确保全局唯一 private static DevComm m_devComm; @@ -60,12 +66,28 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA /** * 插件附加到Flutter引擎时的回调 - * 初始化MethodChannel并设置方法调用处理器 + * 初始化MethodChannel和EventChannel并设置方法调用处理器 */ @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL_NAME); channel.setMethodCallHandler(this); + + // 初始化进度事件通道 + progressEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), EVENT_CHANNEL_NAME); + progressEventChannel.setStreamHandler(new EventChannel.StreamHandler() { + @Override + public void onListen(Object arguments, EventChannel.EventSink events) { + progressEventSink = events; + Log.d(TAG, "进度事件监听已启动"); + } + + @Override + public void onCancel(Object arguments) { + progressEventSink = null; + Log.d(TAG, "进度事件监听已取消"); + } + }); // 注意:这里不应该从ApplicationContext获取Activity,应该等待onAttachedToActivity回调 } @@ -290,24 +312,29 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA final int[] duplicateId = new int[1]; final int[] imageWidth = new int[1]; final int[] imageHeight = new int[1]; - + try { + // 发送开始录入进度事件 + sendProgressEvent(0, ENROLL_STEP_COUNT, "请准备放置手指"); + // 录入指定次数的指纹 while (enrollStep < ENROLL_STEP_COUNT) { Log.d(TAG, String.format("请放置手指进行第%d次录入", enrollStep + 1)); - - // 显示提示信息 - showToastOnMainThread(String.format("请放置手指 (%d/%d)", enrollStep + 1, ENROLL_STEP_COUNT)); + + // 发送进度事件到Flutter + sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT, + String.format("请放置手指 (%d/%d)", enrollStep + 1, ENROLL_STEP_COUNT)); // 采集指纹图像 if (captureFingerprint() < 0) { + sendProgressEvent(-1, ENROLL_STEP_COUNT, "指纹采集失败"); Map errorResult = createErrorResponse("指纹采集失败"); mainHandler.post(() -> result.success(errorResult)); return; } - + Log.d(TAG, "请移开手指"); - showToastOnMainThread("请移开手指"); + sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT, "请移开手指"); // 上传指纹图像(仅USB模式) if (m_devComm.m_nConnected == 2) { @@ -315,6 +342,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA if (uploadResult != DevComm.ERR_SUCCESS) { String errorMsg = GetErrorMsg(uploadResult); Log.e(TAG, "上传指纹图像失败: " + errorMsg); + sendProgressEvent(-1, ENROLL_STEP_COUNT, "上传图像失败: " + errorMsg); Map errorResult = createErrorResponse(errorMsg); mainHandler.post(() -> result.success(errorResult)); return; @@ -326,11 +354,12 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA if (generateResult != DevComm.ERR_SUCCESS) { if (generateResult == DevComm.ERR_BAD_QUALITY) { Log.w(TAG, "指纹质量不佳,请重试"); - showToastOnMainThread("指纹质量不佳,请重试"); + sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT, "指纹质量不佳,请重试"); continue; // 重试当前步骤 } else { String errorMsg = GetErrorMsg(generateResult); Log.e(TAG, "生成指纹特征失败: " + errorMsg); + sendProgressEvent(-1, ENROLL_STEP_COUNT, "生成特征失败: " + errorMsg); Map errorResult = createErrorResponse(errorMsg); mainHandler.post(() -> result.success(errorResult)); return; @@ -340,18 +369,25 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA enrollStep++; } + // 发送合并进度事件 + sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "正在合并指纹特征..."); + // 合并多次录入的特征(如果录入次数大于1) if (ENROLL_STEP_COUNT > 1) { int mergeResult = m_devComm.Run_Merge(0, ENROLL_STEP_COUNT); if (mergeResult != DevComm.ERR_SUCCESS) { String errorMsg = GetErrorMsg(mergeResult); Log.e(TAG, "合并指纹特征失败: " + errorMsg); + sendProgressEvent(-1, ENROLL_STEP_COUNT, "合并失败: " + errorMsg); Map errorResult = createErrorResponse(errorMsg); mainHandler.post(() -> result.success(errorResult)); return; } } + // 发送存储进度事件 + sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "正在存储指纹模板..."); + // 存储指纹模板 int storeResult = m_devComm.Run_StoreChar(userId, 0, duplicateId); if (storeResult != DevComm.ERR_SUCCESS) { @@ -362,6 +398,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA errorMsg = GetErrorMsg(storeResult); } Log.e(TAG, "存储指纹模板失败: " + errorMsg); + sendProgressEvent(-1, ENROLL_STEP_COUNT, "存储失败: " + errorMsg); Map errorResult = createErrorResponse(errorMsg); mainHandler.post(() -> result.success(errorResult)); return; @@ -369,15 +406,16 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA // 录入成功 Log.i(TAG, String.format("指纹录入成功,用户ID: %d", userId)); + sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "指纹录入成功"); Map successResult = createSuccessResponse("指纹录入成功"); successResult.put("userId", userId); mainHandler.post(() -> { - showToastOnMainThread("指纹录入成功"); result.success(successResult); }); - + } catch (Exception e) { Log.e(TAG, "指纹录入过程中发生异常: " + e.getMessage(), e); + sendProgressEvent(-1, ENROLL_STEP_COUNT, "录入异常: " + e.getMessage()); Map errorResult = createErrorResponse("录入过程发生异常: " + e.getMessage()); mainHandler.post(() -> result.success(errorResult)); } finally { @@ -810,6 +848,30 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA }); } } + + /** + * 发送进度事件到Flutter端 + * @param step 当前步骤(1-3) + * @param totalSteps 总步骤数(3) + * @param message 进度消息 + */ + private void sendProgressEvent(int step, int totalSteps, String message) { + if (progressEventSink != null) { + mainHandler.post(() -> { + try { + Map progressData = new HashMap<>(); + progressData.put("step", step); + progressData.put("totalSteps", totalSteps); + progressData.put("progress", (double) step / totalSteps); + progressData.put("message", message); + progressEventSink.success(progressData); + Log.d(TAG, "发送进度事件: step=" + step + "/" + totalSteps + ", message=" + message); + } catch (Exception e) { + Log.w(TAG, "发送进度事件失败: " + e.getMessage()); + } + }); + } + } /** * 采集指纹图像(重命名原Capturing方法) @@ -822,13 +884,20 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { Log.d(TAG, "插件从引擎分离"); - - // 清理资源 + + // 清理进度事件通道 + if (progressEventChannel != null) { + progressEventChannel.setStreamHandler(null); + progressEventChannel = null; + progressEventSink = null; + } + + // 清理方法通道 if (channel != null) { channel.setMethodCallHandler(null); channel = null; } - + // 关闭设备连接 if (m_devComm != null && m_devComm.IsInit()) { try { @@ -838,7 +907,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA Log.e(TAG, "关闭设备连接时发生异常: " + e.getMessage()); } } - + // 关闭线程池 if (executorService != null && !executorService.isShutdown()) { executorService.shutdown(); diff --git a/lib/zhiwen.dart b/lib/zhiwen.dart index 596017f..4a6db9a 100644 --- a/lib/zhiwen.dart +++ b/lib/zhiwen.dart @@ -1,5 +1,6 @@ import 'zhiwen_platform_interface.dart'; +import 'dart:async'; class Zhiwen { Future getPlatformVersion() { @@ -37,4 +38,10 @@ class Zhiwen { Future> getUserCount() { return ZhiwenPlatform.instance.getUserCount(); } + + /// 获取指纹录入进度事件流 + /// 返回包含 step, totalSteps, progress, message 的 Map + Stream> get progressStream { + return ZhiwenPlatform.instance.progressStream; + } } diff --git a/lib/zhiwen_method_channel.dart b/lib/zhiwen_method_channel.dart index 097e55e..1d86ba1 100644 --- a/lib/zhiwen_method_channel.dart +++ b/lib/zhiwen_method_channel.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'dart:async'; import 'zhiwen_platform_interface.dart'; @@ -9,6 +10,13 @@ class MethodChannelZhiwen extends ZhiwenPlatform { @visibleForTesting final methodChannel = const MethodChannel('zhiwen'); + /// The event channel for receiving fingerprint enrollment progress. + @visibleForTesting + final progressEventChannel = const EventChannel('zhiwen_progress'); + + /// 进度事件流控制器 + Stream>? _progressStream; + @override Future getPlatformVersion() async { final version = await methodChannel.invokeMethod('getPlatformVersion'); @@ -64,4 +72,13 @@ class MethodChannelZhiwen extends ZhiwenPlatform { final result = await methodChannel.invokeMethod('getUserCount'); return Map.from(result as Map); } + + /// 获取指纹录入进度事件流 + @override + Stream> get progressStream { + _progressStream ??= progressEventChannel + .receiveBroadcastStream() + .map((event) => Map.from(event as Map)); + return _progressStream!; + } } diff --git a/lib/zhiwen_platform_interface.dart b/lib/zhiwen_platform_interface.dart index 5500956..41f472e 100644 --- a/lib/zhiwen_platform_interface.dart +++ b/lib/zhiwen_platform_interface.dart @@ -1,4 +1,5 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'dart:async'; import 'zhiwen_method_channel.dart'; @@ -24,6 +25,11 @@ abstract class ZhiwenPlatform extends PlatformInterface { Future> deleteOneFingerprint(int userId); Future> identifyFingerprint(); Future> getUserCount(); + + /// 获取指纹录入进度事件流 + /// 返回包含 step, totalSteps, progress, message 的 Map + Stream> get progressStream; + /// Platform-specific implementations should set this with their own /// platform-specific class that extends [ZhiwenPlatform] when /// they register themselves.