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;
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||||
import io.flutter.plugin.common.MethodChannel.Result;
|
import io.flutter.plugin.common.MethodChannel.Result;
|
||||||
|
import io.flutter.plugin.common.EventChannel;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
// 常量定义
|
// 常量定义
|
||||||
private static final String TAG = "ZhiwenPlugin";
|
private static final String TAG = "ZhiwenPlugin";
|
||||||
private static final String CHANNEL_NAME = "zhiwen";
|
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 DEFAULT_MAX_FP_COUNT = 3000;
|
||||||
private static final int ENROLL_STEP_COUNT = 3;
|
private static final int ENROLL_STEP_COUNT = 3;
|
||||||
private static final int IMAGE_BUFFER_SIZE = 1024 * 100;
|
private static final int IMAGE_BUFFER_SIZE = 1024 * 100;
|
||||||
@@ -45,6 +47,10 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
/// 用于注册插件到Flutter引擎,并在Activity分离时注销
|
/// 用于注册插件到Flutter引擎,并在Activity分离时注销
|
||||||
private MethodChannel channel;
|
private MethodChannel channel;
|
||||||
|
|
||||||
|
/// 进度事件通道,用于向Flutter发送指纹录入进度
|
||||||
|
private EventChannel progressEventChannel;
|
||||||
|
private EventChannel.EventSink progressEventSink;
|
||||||
|
|
||||||
// 设备通信对象,使用static确保全局唯一
|
// 设备通信对象,使用static确保全局唯一
|
||||||
private static DevComm m_devComm;
|
private static DevComm m_devComm;
|
||||||
|
|
||||||
@@ -60,12 +66,28 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件附加到Flutter引擎时的回调
|
* 插件附加到Flutter引擎时的回调
|
||||||
* 初始化MethodChannel并设置方法调用处理器
|
* 初始化MethodChannel和EventChannel并设置方法调用处理器
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
||||||
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL_NAME);
|
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL_NAME);
|
||||||
channel.setMethodCallHandler(this);
|
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回调
|
// 注意:这里不应该从ApplicationContext获取Activity,应该等待onAttachedToActivity回调
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,22 +314,27 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
final int[] imageHeight = new int[1];
|
final int[] imageHeight = new int[1];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 发送开始录入进度事件
|
||||||
|
sendProgressEvent(0, ENROLL_STEP_COUNT, "请准备放置手指");
|
||||||
|
|
||||||
// 录入指定次数的指纹
|
// 录入指定次数的指纹
|
||||||
while (enrollStep < ENROLL_STEP_COUNT) {
|
while (enrollStep < ENROLL_STEP_COUNT) {
|
||||||
Log.d(TAG, String.format("请放置手指进行第%d次录入", enrollStep + 1));
|
Log.d(TAG, String.format("请放置手指进行第%d次录入", enrollStep + 1));
|
||||||
|
|
||||||
// 显示提示信息
|
// 发送进度事件到Flutter
|
||||||
showToastOnMainThread(String.format("请放置手指 (%d/%d)", enrollStep + 1, ENROLL_STEP_COUNT));
|
sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT,
|
||||||
|
String.format("请放置手指 (%d/%d)", enrollStep + 1, ENROLL_STEP_COUNT));
|
||||||
|
|
||||||
// 采集指纹图像
|
// 采集指纹图像
|
||||||
if (captureFingerprint() < 0) {
|
if (captureFingerprint() < 0) {
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "指纹采集失败");
|
||||||
Map<String, Object> errorResult = createErrorResponse("指纹采集失败");
|
Map<String, Object> errorResult = createErrorResponse("指纹采集失败");
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "请移开手指");
|
Log.d(TAG, "请移开手指");
|
||||||
showToastOnMainThread("请移开手指");
|
sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT, "请移开手指");
|
||||||
|
|
||||||
// 上传指纹图像(仅USB模式)
|
// 上传指纹图像(仅USB模式)
|
||||||
if (m_devComm.m_nConnected == 2) {
|
if (m_devComm.m_nConnected == 2) {
|
||||||
@@ -315,6 +342,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
if (uploadResult != DevComm.ERR_SUCCESS) {
|
if (uploadResult != DevComm.ERR_SUCCESS) {
|
||||||
String errorMsg = GetErrorMsg(uploadResult);
|
String errorMsg = GetErrorMsg(uploadResult);
|
||||||
Log.e(TAG, "上传指纹图像失败: " + errorMsg);
|
Log.e(TAG, "上传指纹图像失败: " + errorMsg);
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "上传图像失败: " + errorMsg);
|
||||||
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
return;
|
return;
|
||||||
@@ -326,11 +354,12 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
if (generateResult != DevComm.ERR_SUCCESS) {
|
if (generateResult != DevComm.ERR_SUCCESS) {
|
||||||
if (generateResult == DevComm.ERR_BAD_QUALITY) {
|
if (generateResult == DevComm.ERR_BAD_QUALITY) {
|
||||||
Log.w(TAG, "指纹质量不佳,请重试");
|
Log.w(TAG, "指纹质量不佳,请重试");
|
||||||
showToastOnMainThread("指纹质量不佳,请重试");
|
sendProgressEvent(enrollStep + 1, ENROLL_STEP_COUNT, "指纹质量不佳,请重试");
|
||||||
continue; // 重试当前步骤
|
continue; // 重试当前步骤
|
||||||
} else {
|
} else {
|
||||||
String errorMsg = GetErrorMsg(generateResult);
|
String errorMsg = GetErrorMsg(generateResult);
|
||||||
Log.e(TAG, "生成指纹特征失败: " + errorMsg);
|
Log.e(TAG, "生成指纹特征失败: " + errorMsg);
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "生成特征失败: " + errorMsg);
|
||||||
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
return;
|
return;
|
||||||
@@ -340,18 +369,25 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
enrollStep++;
|
enrollStep++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送合并进度事件
|
||||||
|
sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "正在合并指纹特征...");
|
||||||
|
|
||||||
// 合并多次录入的特征(如果录入次数大于1)
|
// 合并多次录入的特征(如果录入次数大于1)
|
||||||
if (ENROLL_STEP_COUNT > 1) {
|
if (ENROLL_STEP_COUNT > 1) {
|
||||||
int mergeResult = m_devComm.Run_Merge(0, ENROLL_STEP_COUNT);
|
int mergeResult = m_devComm.Run_Merge(0, ENROLL_STEP_COUNT);
|
||||||
if (mergeResult != DevComm.ERR_SUCCESS) {
|
if (mergeResult != DevComm.ERR_SUCCESS) {
|
||||||
String errorMsg = GetErrorMsg(mergeResult);
|
String errorMsg = GetErrorMsg(mergeResult);
|
||||||
Log.e(TAG, "合并指纹特征失败: " + errorMsg);
|
Log.e(TAG, "合并指纹特征失败: " + errorMsg);
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "合并失败: " + errorMsg);
|
||||||
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送存储进度事件
|
||||||
|
sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "正在存储指纹模板...");
|
||||||
|
|
||||||
// 存储指纹模板
|
// 存储指纹模板
|
||||||
int storeResult = m_devComm.Run_StoreChar(userId, 0, duplicateId);
|
int storeResult = m_devComm.Run_StoreChar(userId, 0, duplicateId);
|
||||||
if (storeResult != DevComm.ERR_SUCCESS) {
|
if (storeResult != DevComm.ERR_SUCCESS) {
|
||||||
@@ -362,6 +398,7 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
errorMsg = GetErrorMsg(storeResult);
|
errorMsg = GetErrorMsg(storeResult);
|
||||||
}
|
}
|
||||||
Log.e(TAG, "存储指纹模板失败: " + errorMsg);
|
Log.e(TAG, "存储指纹模板失败: " + errorMsg);
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "存储失败: " + errorMsg);
|
||||||
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
Map<String, Object> errorResult = createErrorResponse(errorMsg);
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
return;
|
return;
|
||||||
@@ -369,15 +406,16 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
|
|
||||||
// 录入成功
|
// 录入成功
|
||||||
Log.i(TAG, String.format("指纹录入成功,用户ID: %d", userId));
|
Log.i(TAG, String.format("指纹录入成功,用户ID: %d", userId));
|
||||||
|
sendProgressEvent(ENROLL_STEP_COUNT, ENROLL_STEP_COUNT, "指纹录入成功");
|
||||||
Map<String, Object> successResult = createSuccessResponse("指纹录入成功");
|
Map<String, Object> successResult = createSuccessResponse("指纹录入成功");
|
||||||
successResult.put("userId", userId);
|
successResult.put("userId", userId);
|
||||||
mainHandler.post(() -> {
|
mainHandler.post(() -> {
|
||||||
showToastOnMainThread("指纹录入成功");
|
|
||||||
result.success(successResult);
|
result.success(successResult);
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "指纹录入过程中发生异常: " + e.getMessage(), e);
|
Log.e(TAG, "指纹录入过程中发生异常: " + e.getMessage(), e);
|
||||||
|
sendProgressEvent(-1, ENROLL_STEP_COUNT, "录入异常: " + e.getMessage());
|
||||||
Map<String, Object> errorResult = createErrorResponse("录入过程发生异常: " + e.getMessage());
|
Map<String, Object> errorResult = createErrorResponse("录入过程发生异常: " + e.getMessage());
|
||||||
mainHandler.post(() -> result.success(errorResult));
|
mainHandler.post(() -> result.success(errorResult));
|
||||||
} finally {
|
} finally {
|
||||||
@@ -811,6 +849,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方法)
|
* 采集指纹图像(重命名原Capturing方法)
|
||||||
* @return 采集结果,0表示成功,负数表示失败
|
* @return 采集结果,0表示成功,负数表示失败
|
||||||
@@ -823,7 +885,14 @@ public class ZhiwenPlugin implements FlutterPlugin, MethodCallHandler, ActivityA
|
|||||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
Log.d(TAG, "插件从引擎分离");
|
Log.d(TAG, "插件从引擎分离");
|
||||||
|
|
||||||
// 清理资源
|
// 清理进度事件通道
|
||||||
|
if (progressEventChannel != null) {
|
||||||
|
progressEventChannel.setStreamHandler(null);
|
||||||
|
progressEventChannel = null;
|
||||||
|
progressEventSink = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理方法通道
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
channel = null;
|
channel = null;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import 'zhiwen_platform_interface.dart';
|
import 'zhiwen_platform_interface.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
class Zhiwen {
|
class Zhiwen {
|
||||||
Future<String?> getPlatformVersion() {
|
Future<String?> getPlatformVersion() {
|
||||||
@@ -37,4 +38,10 @@ class Zhiwen {
|
|||||||
Future<Map<String, dynamic>> getUserCount() {
|
Future<Map<String, dynamic>> getUserCount() {
|
||||||
return ZhiwenPlatform.instance.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/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'zhiwen_platform_interface.dart';
|
import 'zhiwen_platform_interface.dart';
|
||||||
|
|
||||||
@@ -9,6 +10,13 @@ class MethodChannelZhiwen extends ZhiwenPlatform {
|
|||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
final methodChannel = const MethodChannel('zhiwen');
|
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
|
@override
|
||||||
Future<String?> getPlatformVersion() async {
|
Future<String?> getPlatformVersion() async {
|
||||||
final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
|
final version = await methodChannel.invokeMethod<String>('getPlatformVersion');
|
||||||
@@ -64,4 +72,13 @@ class MethodChannelZhiwen extends ZhiwenPlatform {
|
|||||||
final result = await methodChannel.invokeMethod('getUserCount');
|
final result = await methodChannel.invokeMethod('getUserCount');
|
||||||
return Map<String, dynamic>.from(result as Map);
|
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 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'zhiwen_method_channel.dart';
|
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>> deleteOneFingerprint(int userId);
|
||||||
Future<Map<String, dynamic>> identifyFingerprint();
|
Future<Map<String, dynamic>> identifyFingerprint();
|
||||||
Future<Map<String, dynamic>> getUserCount();
|
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 implementations should set this with their own
|
||||||
/// platform-specific class that extends [ZhiwenPlatform] when
|
/// platform-specific class that extends [ZhiwenPlatform] when
|
||||||
/// they register themselves.
|
/// they register themselves.
|
||||||
|
|||||||
Reference in New Issue
Block a user