Android 14锁屏启动应用时NFC前台分发注册异常咨询
Android 14锁屏启动应用时NFC前台分发异常的解决方案
问题分析
Android 14系统中,锁屏状态下启动应用时,系统会主动触发Activity的onResume/onPause生命周期回调,但此时应用实际处于后台状态,窗口未获得焦点也不可见。此前直接在onResume中调用NfcAdapter.enableForegroundDispatch()注册NFC前台分发的逻辑,会因系统的严格校验抛出IllegalStateException(提示“Foreground dispatch can only be enabled/disabled when your activity is in foreground”)。旧版本系统未出现此问题,要么是该场景下未触发onResume回调,要么是系统未对前台状态做严格校验。
正确的判断逻辑
要确定是否可以注册NFC Intent,不能仅依赖生命周期回调,必须结合Activity的实际可见状态和窗口焦点状态:
- 核心判断条件:同时满足Activity处于
RESUMED生命周期状态,且窗口获得焦点(isWindowFocused()返回true)。这两个条件同时成立时,Activity才真正处于前台可见状态,符合NFC前台分发的调用要求。
代码实现示例
方案1:在onResume中增加校验
@Override protected void onResume() { super.onResume(); // 仅当Activity真正前台可见时注册NFC分发 if (isResumed() && isWindowFocused()) { NfcUtil.registerForNfcIntents(this); } } @Override protected void onPause() { super.onPause(); // 无论是否前台,onPause时注销分发,避免内存泄漏 NfcUtil.unregisterForNfcIntents(this); }
方案2:结合onWindowFocusChanged处理
窗口焦点变化能更精准地反映Activity是否真正处于前台,适合锁屏/解锁场景:
@Override protected void onResume() { super.onResume(); // 初始状态校验 if (isWindowFocused()) { NfcUtil.registerForNfcIntents(this); } } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus && isResumed()) { // 窗口获得焦点且处于RESUMED状态,注册分发 NfcUtil.registerForNfcIntents(this); } else { // 窗口失去焦点,注销分发 NfcUtil.unregisterForNfcIntents(this); } } @Override protected void onPause() { super.onPause(); NfcUtil.unregisterForNfcIntents(this); }
注意事项
- Android 14对NFC前台分发的校验逻辑更严格,必须确保调用
enableForegroundDispatch()时Activity处于真正的前台可见状态; - 务必在
onPause或窗口失去焦点时注销NFC前台分发,避免资源泄漏和异常。
内容的提问来源于stack exchange,提问作者johnnyb
相关产品推荐
相关产品推荐

