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

Android Kotlin获取Mifare Classic标签UID失败问题排查

你的原实现踩坑点分析及解决方向

1. 技术过滤配置漏了关键项

你配置的NFC技术过滤文件里可能只写了MifareClassic,但Mifare Classic标签底层是基于NfcA协议的,索尼Xperia系列设备要求必须先匹配NfcA才能触发App的NFC Intent。第三方App能识别是因为它们同时监听了NfcA和MifareClassic。
正确的<tech-list>要同时包含两者:

<tech-list>
    <tech>android.nfc.tech.NfcA</tech>
    <tech>android.nfc.tech.MifareClassic</tech>
</tech-list>

2. Intent获取的时机不对

很多新手只会在onCreate里调用getIntent()拿NFC数据,但如果App已经在前台,NFC触发的Intent会通过onNewIntent传递,Android 9的索尼设备对这个逻辑卡得更严。
正确的处理逻辑:

  • 在onCreate里检查启动Intent是否是NFC触发的;
  • 重写onNewIntent方法,专门处理后续的NFC触发事件;
  • 给Activity设置android:launchMode="singleTop",避免重复创建Activity实例,确保Intent能正确传递到onNewIntent。

3. Manifest配置有遗漏

没加singleTop启动模式,或者权限声明不完整,都可能导致系统不把NFC Intent传给你的App。检查Manifest里的Activity配置:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED"/>
    </intent-filter>
    <meta-data
        android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/nfc_tech_filter"/>
</activity>

别忘了声明<uses-permission android:name="android.permission.NFC"/>和<uses-feature android:name="android.hardware.nfc" android:required="true"/>。

4. Mifare Classic的设备兼容性问题

索尼部分设备不会直接把标签映射为MifareClassic对象,哪怕第三方App能识别。这就是你用NFCReader项目能拿到UID但识别不了MifareClassic的原因——第三方App是直接从NfcA标签里读UID,不依赖MifareClassic类。
要获取UID的话,直接从Tag对象拿就行,不用纠结是不是MifareClassic:

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] uid = tag.getId();

5. 前台调度没配置好

如果你的App是前台运行时读标签,必须开启前台调度模式,否则系统会把NFC Intent传给其他优先级更高的App(比如你提到的TagInfo)。原代码可能没做这部分,导致收不到Intent。
在onResume里加这段:

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
        new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter[] filters = new IntentFilter[]{new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)};
String[][] techLists = new String[][]{{NfcA.class.getName(), MifareClassic.class.getName()}};
nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, techLists);

onPause里记得调用nfcAdapter.disableForegroundDispatch(this)关闭。

内容的提问来源于stack exchange,提问作者Green

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:52:43