You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:26:06