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

无需Android Beam或HCE,Android能否实现NFC P2P通信以交换联系人?

解决方案:Android 14+ 实现NFC对等联系人交换(替代NameDrop)

方案1:NDEF标签双向读写模拟

核心思路是让两部设备同时开启NFC读写模式,碰一碰时互相读取对方模拟的NDEF标签,同时自身也提供包含联系人信息的NDEF数据,实现双向交换。

  • 实现步骤:

    1. 注册NFC前台调度,过滤NDEF_DISCOVERED和TECH_DISCOVERED意图,同时支持读写权限。
    2. 检测到设备触碰时,优先读取对方的NDEF消息获取联系人,同时将自身联系人写入本地模拟的NDEF标签供对方读取。
    3. 加入会话ID验证:交换前先传递随机生成的会话ID,仅当双方ID匹配时完成联系人导入,避免重复操作或读取无关标签。
  • 核心代码片段:

// 初始化NFC适配器
val nfcAdapter = NfcAdapter.getDefaultAdapter(context)
// 封装联系人信息为NDEF记录
val contactRecord = NdefRecord.createMime(
    "application/vnd.your.app.contact",
    Gson().toJson(localContact).toByteArray()
)
val ndefMessage = NdefMessage(arrayOf(contactRecord))

// 设置前台调度
val pendingIntent = PendingIntent.getActivity(
    context,
    0,
    Intent(context, MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
    PendingIntent.FLAG_MUTABLE
)
val filters = arrayOf(IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
    addDataType("application/vnd.your.app.contact")
})
val techLists = arrayOf(arrayOf(Ndef::class.java.name))
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, filters, techLists)

// 处理触碰事件
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent?.action) {
        // 读取对方联系人
        intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.firstOrNull()?.let { msg ->
            val payload = (msg as NdefMessage).records.first().payload
            val receivedContact = Gson().fromJson(String(payload), Contact::class.java)
            importToContacts(receivedContact)
        }
        // 让对方读取自身联系人
        writeLocalNdefMessage(ndefMessage)
    }
}
  • 权限配置(AndroidManifest.xml):
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

方案2:LLCP底层协议实现

Android Beam虽被弃用,但NFC P2P的底层LLCP(Logical Link Control Protocol)仍可通过NfcAdapter的原生方法调用,实现双向套接字通信。

  • 实现步骤:

    1. 双方同时尝试创建LLCP套接字,先以服务器角色监听,若超时则切换为客户端发起连接,自动适配主从角色。
    2. 连接建立后,双向传输联系人数据字节流。
    3. 通信完成后主动关闭套接字,释放资源。
  • 核心代码片段:

// 初始化LLCP套接字
val socket = nfcAdapter.createLlcpSocket("com.your.app.nfc.service")
try {
    socket.connect()
    val outputStream = socket.outputStream
    val inputStream = socket.inputStream

    // 发送本地联系人数据
    outputStream.write(Gson().toJson(localContact).toByteArray())
    outputStream.flush()

    // 接收对方联系人数据
    val buffer = ByteArray(1024)
    val readSize = inputStream.read(buffer)
    val receivedContact = Gson().fromJson(String(buffer, 0, readSize), Contact::class.java)
    importToContacts(receivedContact)
} catch (e: IOException) {
    // 连接失败则切换角色重试
    switchToClientMode()
} finally {
    socket.close()
}

方案3:NFC+BLE fallback增强兼容性

针对部分不支持NFC P2P的设备,可添加BLE双向通信作为 fallback:

  • 碰一碰时先尝试NFC交换,若超时或失败,自动触发BLE广播与扫描,配对后完成联系人交换。
  • 保持操作流程一致,用户无需感知底层切换。

关键注意事项

  • Android 13+需额外申请POST_NOTIFICATIONS权限,用于向用户推送联系人导入提示。
  • 长时间NFC扫描需使用前台服务,避免被系统后台回收。
  • 加入重复交换拦截:通过设备ID+时间戳判断,短时间内同一设备仅完成一次交换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:47:34