如何向NFC写入应用类载荷,实现触碰后打开指定包名的应用?
NFC写入应用包名实现触碰打开应用的实现方案(Android平台)
该需求可以通过Android系统提供的AAR(Android Application Record)NDEF记录实现,写入对应格式的记录后,设备扫描到NFC标签时会优先匹配记录内的包名,目标应用已安装则直接打开,未安装则自动跳转应用商店对应详情页。
1. 添加基础权限
在AndroidManifest.xml中添加NFC相关权限声明:
<!-- NFC访问权限 --> <uses-permission android:name="android.permission.NFC" /> <!-- 声明应用需要NFC硬件,若不是核心功能可将required设为false --> <uses-feature android:name="android.hardware.nfc" android:required="false" />
2. 配置写入页面的意图过滤
在负责NFC写入操作的Activity的manifest配置中添加意图过滤,接收NFC扫描事件:
<activity android:name=".NfcWriteActivity"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/com.yourapp.package" /> </intent-filter> </activity>
3. 核心写入逻辑实现
3.1 初始化NFC相关组件
在写入Activity的onCreate方法中初始化NFC适配器,绑定Button点击事件:
private NfcAdapter nfcAdapter; private PendingIntent pendingIntent; private boolean isReadyToWrite = false; // 替换为你要启动的目标应用的包名 private static final String TARGET_PACKAGE = "com.example.targetapp"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nfc_write); nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "设备不支持NFC", Toast.LENGTH_SHORT).show(); finish(); return; } pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE); // 绑定写入按钮点击事件 Button writeBtn = findViewById(R.id.write_btn); writeBtn.setOnClickListener(v -> { isReadyToWrite = true; Toast.makeText(this, "请将NFC标签贴近设备背面", Toast.LENGTH_SHORT).show(); }); }
3.2 启用前台分发优先捕获NFC事件
重写生命周期方法开启/关闭NFC前台分发,避免NFC事件被其他应用拦截:
@Override protected void onResume() { super.onResume(); if (nfcAdapter != null) { nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null); } } @Override protected void onPause() { super.onPause(); if (nfcAdapter != null) { nfcAdapter.disableForegroundDispatch(this); } }
3.3 写入AAR记录到NFC标签
重写onNewIntent方法处理扫描到的NFC标签,执行写入操作:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); String action = intent.getAction(); // 仅在待写入状态下处理NFC扫描事件 if (!isReadyToWrite || (!NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) && !NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) { return; } Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 构造AAR类型的NDEF记录 NdefRecord aarRecord = NdefRecord.createApplicationRecord(TARGET_PACKAGE); NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{aarRecord}); Ndef ndef = null; NdefFormatable formatable = null; try { ndef = Ndef.get(tag); if (ndef != null) { ndef.connect(); if (!ndef.isWritable()) { Toast.makeText(this, "该NFC标签不可写入", Toast.LENGTH_SHORT).show(); return; } if (ndef.getMaxSize() < ndefMessage.toByteArray().length) { Toast.makeText(this, "NFC标签容量不足", Toast.LENGTH_SHORT).show(); return; } ndef.writeNdefMessage(ndefMessage); Toast.makeText(this, "写入成功", Toast.LENGTH_SHORT).show(); isReadyToWrite = false; } else { // 标签未格式化为NDEF,尝试格式化后写入 formatable = NdefFormatable.get(tag); if (formatable != null) { formatable.connect(); formatable.format(ndefMessage); Toast.makeText(this, "格式化并写入成功", Toast.LENGTH_SHORT).show(); isReadyToWrite = false; } else { Toast.makeText(this, "不支持的标签类型", Toast.LENGTH_SHORT).show(); } } } catch (IOException | FormatException e) { Toast.makeText(this, "写入失败,请重试", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } finally { // 关闭连接释放资源 try { if (ndef != null) ndef.close(); if (formatable != null) formatable.close(); } catch (IOException e) { e.printStackTrace(); } } }
注意事项
- 仅Android 4.0(API 14)及以上版本支持AAR记录,低版本系统无法识别该类载荷
- 写入使用的NFC标签需要支持NDEF格式,市面上普通的NTAG213/215/216系列标签都满足要求
- 如果需要同时写入文本、链接等其他载荷,只需要将对应NDEF记录放在数组的前序位置,AAR记录放在最后即可
内容的提问来源于stack exchange,提问作者LordCod2
相关产品推荐
相关产品推荐

