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

如何通过NFC在两台设备间传输字符串?技术求助

Android NFC 字符串传输实现方案

核心原理

Android NFC传输小字符串无需依赖蓝牙,直接使用**NDEF(NFC Data Exchange Format)**标准即可,这是NFC论坛定义的通用数据格式,Android原生支持。

1. 配置权限

在AndroidManifest.xml中添加NFC相关权限和硬件声明:

<uses-permission android:name="android.permission.NFC" />
<uses-feature
    android:name="android.hardware.nfc"
    android:required="true" />

2. 发送端实现

通过NfcAdapter的回调创建并推送NDEF消息:

public class SenderActivity extends AppCompatActivity implements
        NfcAdapter.CreateNdefMessageCallback,
        NfcAdapter.OnNdefPushCompleteCallback {

    private NfcAdapter mNfcAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sender);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mNfcAdapter != null) {
            // 设置NDEF消息创建回调
            mNfcAdapter.setNdefPushMessageCallback(this, this);
            // 设置推送完成回调(可选)
            mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
        }
    }

    // 生成要发送的NDEF消息
    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        // 替换为你要传输的字符串
        String content = "Hello NFC!";
        // 创建文本类型的NDEF记录
        NdefRecord textRecord = NdefRecord.createTextRecord("zh", content);
        return new NdefMessage(new NdefRecord[]{textRecord});
    }

    // 推送完成后的UI提示(可选)
    @Override
    public void onNdefPushComplete(NfcEvent event) {
        runOnUiThread(() -> {
            Toast.makeText(this, "字符串已发送", Toast.LENGTH_SHORT).show();
        });
    }
}

3. 接收端实现

通过前台调度拦截NFC意图,解析NDEF消息获取字符串:

public class ReceiverActivity extends AppCompatActivity {

    private NfcAdapter mNfcAdapter;
    private PendingIntent mPendingIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receiver);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        
        // 创建用于接收NFC事件的PendingIntent
        mPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
                PendingIntent.FLAG_MUTABLE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mNfcAdapter != null) {
            // 拦截text/plain类型的NDEF消息
            IntentFilter ndefFilter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
            try {
                ndefFilter.addDataType("text/plain");
            } catch (IntentFilter.MalformedMimeTypeException e) {
                throw new RuntimeException("Invalid MIME type", e);
            }
            IntentFilter[] filters = new IntentFilter[]{ndefFilter};
            // 启用前台调度,确保当前Activity优先处理NFC事件
            mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, filters, null);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mNfcAdapter != null) {
            mNfcAdapter.disableForegroundDispatch(this);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        handleNfcIntent(intent);
    }

    private void handleNfcIntent(Intent intent) {
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
            Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMessages != null && rawMessages.length > 0) {
                NdefMessage ndefMessage = (NdefMessage) rawMessages[0];
                NdefRecord record = ndefMessage.getRecords()[0];
                try {
                    // 解析文本记录:第一个字节是语言编码长度,跳过之后取UTF-8内容
                    String receivedText = new String(record.getPayload(), 1,
                            record.getPayload().length - 1, StandardCharsets.UTF_8);
                    // 处理接收到的字符串,比如显示在UI上
                    Toast.makeText(this, "收到内容: " + receivedText, Toast.LENGTH_LONG).show();
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

关键注意事项

  • 两台设备必须开启NFC并处于屏幕解锁状态
  • 传输时需将设备NFC感应区域贴近(通常在背部,距离不超过5厘米)
  • 单条NDEF消息容量有限(约1KB),过长字符串需拆分记录
  • 官方文档提及的蓝牙文件传输是针对大文件场景,小字符串用NFC NDEF完全独立实现,无需蓝牙

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:31:13