如何在同一Activity中同时使用NFC与Camera服务
同一Activity中同时使用NFC与Camera服务的问题
NFC、Camera两项服务单独使用时均运行正常,但在同一Activity中同时使用两者时,NFC读取器无法工作——打开相机时,NFC读取器轮询会被自动禁用。
以下是切换Activity时(带相机的Activity -> 不带相机的Activity)的应用日志:
I isNFCAllowed is called for userId - 0 D NFC checking for 0 W container manager null for 0 I allow NFC for 0 D call the applyRouting I [INFO:NativeNfcManager.cpp(2044)] nfcManager_enableDiscovery: enter I [INFO:NativeNfcManager.cpp(4265)] storeLastDiscoveryParams: enter I [INFO:NativeNfcManager.cpp(2083)] nfcManager_enableDiscovery: enter; tech_mask = 01, restart = 1 I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=0 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 31 I [INFO:NativeNfcManager.cpp(610)] nfaConnectionCallback: NFA_RF_DISCOVERY_STOPPED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4191)] stopPolling_rfDiscoveryDisabled: disable polling I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 1 I [INFO:NativeNfcManager.cpp(590)] nfaConnectionCallback: NFA_POLL_DISABLED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4169)] startPolling_rfDiscoveryDisabled: enable polling I [INFO:NativeNfcManager.cpp(4173)] startPolling_rfDiscoveryDisabled: wait for enable event I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 0 I [INFO:NativeNfcManager.cpp(581)] nfaConnectionCallback: NFA_POLL_ENABLED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(2115)] nfcManager_enableDiscovery: Enable p2pListening I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=1 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 37 I [INFO:NativeNfcManager.cpp(1030)] nfaConnectionCallback: unknown event ???? I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 30 I [INFO:NativeNfcManager.cpp(600)] nfaConnectionCallback: NFA_RF_DISCOVERY_STARTED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4128)] startStopPolling: enter; isStart=1 I [INFO:NativeNfcManager.cpp(1193)] nfaDeviceManagementCallback: enter; event=0x2 I [INFO:NativeNfcManager.cpp(1222)] nfaDeviceManagementCallback: NFA_DM_SET_CONFIG_EVT I [INFO:NativeNfcManager.cpp(4156)] startStopPolling: exit I [INFO:NativeNfcManager.cpp(2190)] nfcManager_enableDiscovery: exit I Notify nfc service : camera open was(true) -> now(false) = polling(false) D call the applyRouting I [INFO:NativeNfcManager.cpp(2044)] nfcManager_enableDiscovery: enter I [INFO:NativeNfcManager.cpp(4265)] storeLastDiscoveryParams: enter I [INFO:NativeNfcManager.cpp(2083)] nfcManager_enableDiscovery: enter; tech_mask = 00, restart = 1 I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=0 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 31 I [INFO:NativeNfcManager.cpp(610)] nfaConnectionCallback: NFA_RF_DISCOVERY_STOPPED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4191)] stopPolling_rfDiscoveryDisabled: disable polling I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 1 I [INFO:NativeNfcManager.cpp(590)] nfaConnectionCallback: NFA_POLL_DISABLED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=1 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 30 I [INFO:NativeNfcManager.cpp(600)] nfaConnectionCallback: NFA_RF_DISCOVERY_STARTED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(2190)] nfcManager_enableDiscovery: exit **Changed Activity** D call the applyRouting D Discovery configuration equal, not updating. I Notify nfc service : camera open was(false) -> now(true) = polling(true) D call the applyRouting I [INFO:NativeNfcManager.cpp(2044)] nfcManager_enableDiscovery: enter I [INFO:NativeNfcManager.cpp(4265)] storeLastDiscoveryParams: enter I [INFO:NativeNfcManager.cpp(2083)] nfcManager_enableDiscovery: enter; tech_mask = 2f, restart = 1 I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=0 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 31 I [INFO:NativeNfcManager.cpp(610)] nfaConnectionCallback: NFA_RF_DISCOVERY_STOPPED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4191)] stopPolling_rfDiscoveryDisabled: disable polling I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 1 I [INFO:NativeNfcManager.cpp(590)] nfaConnectionCallback: NFA_POLL_DISABLED_EVT: status = 3 I [INFO:NativeNfcManager.cpp(4169)] startPolling_rfDiscoveryDisabled: enable polling I [INFO:NativeNfcManager.cpp(4173)] startPolling_rfDiscoveryDisabled: wait for enable event I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 0 I [INFO:NativeNfcManager.cpp(581)] nfaConnectionCallback: NFA_POLL_ENABLED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(2115)] nfcManager_enableDiscovery: Enable p2pListening I [INFO:NativeNfcManager.cpp(3974)] startRfDiscovery: is start=1 I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 36 I [INFO:NativeNfcManager.cpp(1009)] nfaConnectionCallback: NFA_LISTEN_ENABLED_EVT : status=0x0 I [INFO:NativeNfcManager.cpp(1193)] nfaDeviceManagementCallback: enter; event=0x2 I [INFO:NativeNfcManager.cpp(1222)] nfaDeviceManagementCallback: NFA_DM_SET_CONFIG_EVT I [INFO:NativeNfcManager.cpp(572)] nfaConnectionCallback: event= 30 I [INFO:NativeNfcManager.cpp(600)] nfaConnectionCallback: NFA_RF_DISCOVERY_STARTED_EVT: status = 0 I [INFO:NativeNfcManager.cpp(4128)] startStopPolling: enter; isStart=1 I [INFO:NativeNfcManager.cpp(1193)] nfaDeviceManagementCallback: enter; event=0x2 I [INFO:NativeNfcManager.cpp(1222)] nfaDeviceManagementCallback: NFA_DM_SET_CONFIG_EVT I [INFO:NativeNfcManager.cpp(4156)] startStopPolling: exit I [INFO:NativeNfcManager.cpp(2190)] nfcManager_enableDiscovery: exit
问题分析
从日志中的Notify nfc service : camera open was(false) -> now(true) = polling(true)可以看出,系统在相机启动时会自动触发NFC轮询的禁用逻辑。这是因为部分设备的NFC和Camera模块存在射频干扰,系统默认会在相机激活时暂停NFC的主动轮询,避免互相干扰。
解决办法
1. 相机初始化完成后手动重启NFC轮询
在相机成功打开的回调中,重新启用NFC的前台调度,恢复轮询:
// CameraX示例:在相机启动完成后执行 cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); // 相机初始化逻辑... // 重启NFC NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter != null && nfcAdapter.isEnabled()) { PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE); nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null); } } catch (ExecutionException | InterruptedException e) { e.printStackTrace(); } }, ContextCompat.getMainExecutor(this));
如果使用传统Camera API,可在Camera.open()执行完成或onPreviewFrame回调中执行重启逻辑。
2. 尝试禁用相机的NFC干扰抑制(厂商适配)
部分厂商提供了相机参数选项来关闭NFC干扰检测,可尝试设置对应参数:
// 传统Camera API示例 Camera camera = Camera.open(); Camera.Parameters params = camera.getParameters(); // 不同厂商参数键可能不同,需测试验证 params.set("nfc-intervention", "off"); camera.setParameters(params);
该方法兼容性较差,需针对目标机型测试。
3. 将NFC监听移至后台Service
如果业务场景允许,把NFC的监听逻辑放在后台Service中,而非依赖Activity的前台调度。系统通常不会禁用后台的NFC监听,但会降低NFC读取的实时性,需根据需求权衡。
4. 确认权限配置
确保Manifest中正确声明所需权限和硬件特性:
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.nfc" android:required="false" /> <uses-feature android:name="android.hardware.camera" android:required="false" />
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

