如何为Flutter Android应用配置Zebra MC3300R实现RFID扫描
Zebra MC3300R RFID扫描配置问题
我正在为Flutter Android应用配置Zebra MC3300R设备以实现RFID标签扫描,此前已成功配置RFD8500且运行正常。我能在Zebra MC3300R移动计算机上运行Flutter应用(使用.aar文件,也可通过USB连接运行),但配置MC3300R时出现以下错误日志:
I/flutter ( 8933): Bluetooth permissions granted.
D/RFIDAPI3Error( 8933): RfidUsbMgr: connection failed: device not found
E/MainActivity( 8933): Number of available RFID readers: 0
请问是否有针对MC3300R的不同配置方式?
针对MC3300R的配置调整建议
MC3300R是集成式RFID阅读器(而非RFD8500这类外接蓝牙阅读器),不能沿用蓝牙传输的初始化逻辑,需做以下调整:
修改阅读器传输类型
初始化Readers时,将ENUM_TRANSPORT.BLUETOOTH改为ENUM_TRANSPORT.SERVICE,因为MC3300R的RFID模块是设备内置的,通过系统服务通信:readers = new Readers(this, ENUM_TRANSPORT.SERVICE);添加必要权限
在AndroidManifest.xml中补充内置阅读器所需权限:<uses-permission android:name="com.zebra.rfid.api3.permission.ACCESS_RFID_SERVICE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 12+ 蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />修正触发配置逻辑
原代码中重复设置了StopTrigger类型,需保留唯一配置以适配设备物理按键:TriggerInfo triggerInfo = new TriggerInfo(); triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_HANDHELD); triggerInfo.StartTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED); // 仅保留一个StopTrigger配置 triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_HANDHELD_WITH_TIMEOUT); triggerInfo.StopTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED); triggerInfo.StopTrigger.Handheld.setHandheldTriggerTimeout(0);检查设备RFID服务状态
确保MC3300R设备上的RFID服务已启用:- 打开设备设置,找到"RFID"选项
- 确认RFID模块处于开启状态
- 将"RFID Mode"设置为"Application Controlled"
修改后的完整代码
package com.apptricity.asset_mobile; import android.os.Bundle; import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugin.common.MethodChannel; import com.zebra.rfid.api3.*; import android.util.Log; import java.util.ArrayList; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "com.apptricity.asset_mobile/zebra_rfid"; private Readers readers; private RFIDReader rfidReader; private EventHandler eventHandler; private static final String TAG = "MainActivity"; private MethodChannel channel; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); channel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL); channel.setMethodCallHandler( (call, result) -> { switch (call.method) { case "initializeAndConnect": initializeAndConnect(result); break; case "startInventory": startInventory(); result.success(null); break; case "stopInventory": stopInventory(); result.success(null); break; default: result.notImplemented(); break; } } ); } @Override protected void onDestroy() { super.onDestroy(); try { if (rfidReader != null) { rfidReader.Events.removeEventsListener(eventHandler); rfidReader.disconnect(); rfidReader = null; readers.Dispose(); readers = null; } } catch (InvalidUsageException e) { e.printStackTrace(); } catch (OperationFailureException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } private void initializeAndConnect(MethodChannel.Result result) { try { // 修改传输类型为SERVICE readers = new Readers(this, ENUM_TRANSPORT.SERVICE); ArrayList<ReaderDevice> availableRFIDReaderList = readers.GetAvailableRFIDReaderList(); Log.e(TAG, "Number of available RFID readers: " + availableRFIDReaderList.size()); // 打印可用阅读器详情 for (ReaderDevice readerDevice : availableRFIDReaderList) { String deviceInfo = "Reader Device: " + readerDevice.getName() + ", Address: " + readerDevice.getAddress(); Log.e(TAG, deviceInfo); } if (!availableRFIDReaderList.isEmpty()) { ReaderDevice readerDevice = availableRFIDReaderList.get(0); // 连接第一个可用阅读器 rfidReader = readerDevice.getRFIDReader(); if (!rfidReader.isConnected()) { rfidReader.connect(); ConfigureReader(); result.success(true); } else { result.success(true); } } else { // 无可用阅读器 result.success(false); // 返回失败标识 } } catch (Exception e) { Log.e(TAG, "Error initializing RFID reader", e); } } private void ConfigureReader() { if (rfidReader.isConnected()) { TriggerInfo triggerInfo = new TriggerInfo(); triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_HANDHELD); triggerInfo.StartTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED); // 修正重复设置StopTrigger的问题 triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_HANDHELD_WITH_TIMEOUT); triggerInfo.StopTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED); triggerInfo.StopTrigger.Handheld.setHandheldTriggerTimeout(0); try { if (eventHandler == null) { eventHandler = new EventHandler(channel, rfidReader); } rfidReader.Events.addEventsListener(eventHandler); rfidReader.Events.setHandheldEvent(true); rfidReader.Events.setTagReadEvent(true); rfidReader.Events.setAttachTagDataWithReadEvent(false); rfidReader.Config.setTriggerMode(ENUM_TRIGGER_MODE.RFID_MODE, true); rfidReader.Config.setStartTrigger(triggerInfo.StartTrigger); rfidReader.Config.setStopTrigger(triggerInfo.StopTrigger); } catch (InvalidUsageException | OperationFailureException e) { Log.e(TAG, "Error configuring RFID reader", e); } } } private void startInventory() { if (rfidReader != null) { Log.d(TAG, "RFIDReader is not null. Checking connection..."); if (rfidReader.isConnected()) { Log.d(TAG, "RFIDReader is connected. Attempting to start inventory."); try { rfidReader.Actions.Inventory.perform(); } catch (InvalidUsageException | OperationFailureException e) { Log.e(TAG, "Error starting inventory", e); } } else { Log.e(TAG, "RFIDReader is not initialized or connected."); } } else { Log.e(TAG, "RFIDReader is null."); } } private void stopInventory() { try { rfidReader.Actions.Inventory.stop(); } catch (InvalidUsageException | OperationFailureException e) { Log.e(TAG, "Error stopping inventory", e); } } public class EventHandler implements RfidEventsListener { private MethodChannel channel; private RFIDReader rfidReader; public EventHandler(MethodChannel channel, RFIDReader rfidReader) { this.channel = channel; this.rfidReader = rfidReader; } @Override public void eventReadNotify(RfidReadEvents e) { TagData[] myTags = rfidReader.Actions.getReadTags(100); if (myTags != null && myTags.length > 0) { String firstTagId = myTags[0].getTagID(); Log.d(TAG, "First read tag ID: " + firstTagId); ArrayList<String> tagIdList = new ArrayList<>(); tagIdList.add(firstTagId); runOnUiThread(() -> channel.invokeMethod("onTagRead", tagIdList)); } } @Override public void eventStatusNotify(RfidStatusEvents rfidStatusEvents) { Log.d(TAG, "Status Notification: " + rfidStatusEvents.StatusEventData.getStatusEventType()); if (rfidStatusEvents.StatusEventData.getStatusEventType() == STATUS_EVENT_TYPE.HANDHELD_TRIGGER_EVENT) { HANDHELD_TRIGGER_EVENT_TYPE triggerType = rfidStatusEvents.StatusEventData.HandheldTriggerEventData.getHandheldEvent(); if (triggerType == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED) { // 触发按下逻辑 } else if (triggerType == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED) { // 触发松开逻辑 } } } } }
内容的提问来源于stack exchange,提问作者Anamika Singh
相关产品推荐
相关产品推荐

