在Android14上开发NFC功能

时间:2024-01-24 07:28:54

前言

随着NFC的使用范围越来越广,有望在未来的智能时代发挥更大的作用,NFC的相关功能的开发学习也要提上日程。

本文是基于Android14进行的NDEF读写操作时的重点知识点介绍。

一、配置为系统可分发

AndroidManifest.xml文件中添加intent-filter, 让系统可以知道你的activity支持ndef读卡功能。

<intent-filter>
     <action android:name="android.nfc.action.NDEF_DISCOVERED" />
     <data android:mimeType="*/*" />
</intent-filter>

二、配置前台检测系统

前台检测分为两种,

  • 其一是执行读卡器模式,当前活动直接获取标签信息;
  • 另一种是启动前台调度,也就是当系统检测到NFC标签时,优先提供给当前activity进行处理,如果当前activity不具备处理能力则继续分发给其他应用。

本文以第二种方式为例

  1. 获得NFC处理句柄
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
  1. 设置为前台优先调度模式 设置后,当识别到ndef格式标签时,将会直接交给当前activity处理
private val intentFiltersArray = arrayOf(IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply { addDataType("*/*") }) // 兼容编辑器*/
private val techListsArray = arrayOf(
    arrayOf<String>(NdefFormatable::class.java.name),
    arrayOf<String>(Ndef::class.java.name),
)
val intent = Intent(this, NFCReaderActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
val pendingIntent = PendingIntent.getActivity(
    this, 0, intent,
    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)

三、处理获取到的标签

要获取系统识别到的标签,首先要在onNewIntent方法中得到Tag,然后对Tag进行解析,读取出全部的NDEF Record。

public override fun onNewIntent(intent: Intent) {
   	Log.i(TAG, "onNewIntent: action ${intent.action}")
   	super.onNewIntent(intent)
   	intent.action?.let {
	// 从intent中拿出Tag标签
       	val tagDetected = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
	// 从标签中获取ndef信息
        val ndef = Ndef.get(tag)
		try {
            ndef.connect()
            canMakeReadOnly = ndef.canMakeReadOnly()
            ndef.ndefMessage?.records?.forEach {
				// 读取出全部的record记录
            	Log.i(TAG, "get record: ${it.payload}")
            }
        }catch (e: Exception){
            Log.e(TAG, "read: exception $e")
        }finally {
			ndef.close()
		}
    }
}

四、写入标签数据

当上面获取到Tag并从中获取到ndef实例之后,写入数据就简单了. 以写入普通的文本信息为例

        val msg = NdefMessage(NdefRecord.createTextRecord(null, "hello ndef"))
        val ndef = Ndef.get(tag)
        try {
            ndef.connect()
            ndef.writeNdefMessage(msg)
        }catch (e: Exception){
            Log.e(TAG, "writeMsg: exception - $e")
        }finally {
            ndef.close()
        }

五、附

除了写入普通文本以外,还可以写入uri等多种信息,方便又好用。 image.png

六、项目开源

仅供学习和研究使用。 开源仓库:https://gitee.com/jeadyx/j-nfc-tools