You need to enable JavaScript to run this app. 如何向NFC写入应用类载荷,实现触碰后打开指定包名的应用?
优惠活动
大模型
产品
解决方案
定价
更多

如何向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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 02:15:02