1
This commit is contained in:
@@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import 'zhiwen_platform_interface.dart';
|
||||
import 'dart:async';
|
||||
|
||||
class Zhiwen {
|
||||
Future<String?> getPlatformVersion() {
|
||||
@@ -37,4 +38,10 @@ class Zhiwen {
|
||||
Future<Map<String, dynamic>> getUserCount() {
|
||||
return ZhiwenPlatform.instance.getUserCount();
|
||||
}
|
||||
|
||||
/// 获取指纹录入进度事件流
|
||||
/// 返回包含 step, totalSteps, progress, message 的 Map
|
||||
Stream<Map<String, dynamic>> get progressStream {
|
||||
return ZhiwenPlatform.instance.progressStream;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Map<String, dynamic>>? _progressStream;
|
||||
|
||||
@override
|
||||
Future<String?> getPlatformVersion() async {
|
||||
final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
|
||||
@@ -64,4 +72,13 @@ class MethodChannelZhiwen extends ZhiwenPlatform {
|
||||
final result = await methodChannel.invokeMethod('getUserCount');
|
||||
return Map<String, dynamic>.from(result as Map);
|
||||
}
|
||||
|
||||
/// 获取指纹录入进度事件流
|
||||
@override
|
||||
Stream<Map<String, dynamic>> get progressStream {
|
||||
_progressStream ??= progressEventChannel
|
||||
.receiveBroadcastStream()
|
||||
.map((event) => Map<String, dynamic>.from(event as Map));
|
||||
return _progressStream!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Map<String, dynamic>> deleteOneFingerprint(int userId);
|
||||
Future<Map<String, dynamic>> identifyFingerprint();
|
||||
Future<Map<String, dynamic>> getUserCount();
|
||||
|
||||
/// 获取指纹录入进度事件流
|
||||
/// 返回包含 step, totalSteps, progress, message 的 Map
|
||||
Stream<Map<String, dynamic>> get progressStream;
|
||||
|
||||
/// Platform-specific implementations should set this with their own
|
||||
/// platform-specific class that extends [ZhiwenPlatform] when
|
||||
/// they register themselves.
|
||||
|
||||
Reference in New Issue
Block a user