当前位置: 首页 > article >正文

Android读取NFC卡片数据

这里以nfc公交卡为例子

在这里插入图片描述

使用如下
  1. 请将需要获取nfc数据的 Activity 对应的清单文件里面设置成 栈顶模式,并在intent 标签内添加 action – nfc
    在这里插入图片描述
android:launchMode="singleTop"
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
  1. 在对应Activity内的各个生命周期内加入以下代码
onCreate 创建nfc

在这里插入图片描述

初始化NFC show 里面是说明当前设备是否支持NFC是否打开NFC
在这里插入图片描述

NfcUtil.createNfc(this,object : NfcUtil.NFCCreateBack{
            override fun show(s: String) {
                Log.e("NFC_TAG", "createNfc: -${s}", )
            }
        })

该设备是否支持NFC

NfcUtil.getNFC(this)

跳到手机系统NFC设置界面

NfcUtil.jumpNFC()
onResume 开启nfc监听

在这里插入图片描述

NfcUtil.resumeNfc()
onPause 关闭nfc监听

在这里插入图片描述

NfcUtil.pauseNfc()
onNewIntent 获取监听到的数据

在这里插入图片描述

//这里必须setIntent,set  NFC事件响应后的intent才能拿到数据
        setIntent(intent)
        NfcUtil.resolveIntent(intent!!,object: NfcUtil.NFCBack{
            override fun onSuc(s: NfcUtil.NFCBean) {
                tv1?.text = "名称: ${s.tagID_hex}"
                tv2?.text = "ID: ${s.tagID_dec}"
                tv3?.text = "内存大小: ${s.tagID_size}"
                tv4?.text = "名称: ${s.msg}"
            }

        })

NfcUtil

/**
 * Nfc读取工具类
 * */
@SuppressLint("StaticFieldLeak")
object NfcUtil {

    private var activity: Activity? = null
    var mNfcAdapter: NfcAdapter? = null
    var pIntent: PendingIntent? = null
    lateinit var mIntentFilter: Array<IntentFilter>
    lateinit var mTechList: Array<Array<String>>

    //创建必要数据
    fun createNfc(a: Activity,c: NFCCreateBack){
        activity = a
        mNfcAdapter = NfcAdapter.getDefaultAdapter(activity)
        if (mNfcAdapter == null) {
            c.show("设备不支持NFC!")
        }else{
            if (!mNfcAdapter!!.isEnabled) {
                c.show("请在系统设置中先启用NFC功能!")
            }
            pIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                PendingIntent.getActivity(activity, 0, Intent(activity,activity?.javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE )
            } else {
                PendingIntent.getActivity(activity, 0, Intent(activity, activity?.javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
            }
        }
    }

    //创建回调
    interface NFCCreateBack{
        fun show(s: String)
    }


    //进入界面调用
    fun resumeNfc(){
        mNfcAdapter?.let {
            //intentFilter过滤----ndef
            val ndefFilter = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)
            try {
                //文本类型
                ndefFilter.addDataType("text/plain")
            } catch (e: MalformedMimeTypeException) {
                e.printStackTrace()
            }
            //intentFilter过滤----非ndef
            val techFilter = IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)
            val tag = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)

            //intentFilter过滤器列表
            mIntentFilter = arrayOf(ndefFilter,techFilter,tag)
            //匹配的数据格式列表
            mTechList = arrayOf(
                arrayOf(MifareClassic::class.java.name),
                arrayOf(NfcA::class.java.name),
                arrayOf(Ndef::class.java.name),
                arrayOf(NdefFormatable::class.java.name)
            )
            it.enableForegroundDispatch(activity, pIntent, mIntentFilter, mTechList)
        }
    }

    //去除NFC监听
    fun pauseNfc(){
        mNfcAdapter?.disableForegroundDispatch(activity)
    }

    //处理接收到的NFC数据
    fun resolveIntent(intent: Intent,nfcBack: NFCBack){
        val action = intent.action
        Log.e("NFC_TAG", "action Type: $action")
       if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action) {
            val tag1: Parcelable? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
            if (tag1 != null) {
                Log.e("NFC_TAG", "解析数据: ${dumpTagData66(tag1,nfcBack)}")
                dumpTagData66(tag1,nfcBack)
            }
        }else {
           val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
           var tagIDHex: String = ""
           var tagIDDec: String = ""
           val tagIDSize: String = "1024"
           if (tag != null) {
               val nfcId = dumpTagData(tag)
               tagIDHex = getHex(tag.id).toString()
               tagIDDec = getDec(tag.id).toString()
               if (nfcId.isNotEmpty()) {
                   Log.e("NFC_TAG", "接收到卡片ID: $nfcId")
               } else {
                   Log.e("NFC_TAG", "识别失败!请重新刷卡!")
               }

           }
           nfcBack.onSuc(NFCBean(tagIDHex,tagIDDec,tagIDSize,""))
       }
    }

    //回调
    interface NFCBack{
        fun onSuc(s: NFCBean)
    }

    //数据内容实体类
    data class NFCBean(
        var tagID_hex: String? = "", //id,不同的解析
        var tagID_dec: String? = "", //id,不同的解析
        var tagID_size: String? = "", //id,不同的解析
        var msg: String? = "" //详细数据
    )

    private fun dumpTagData(p: Tag): String {
        val id = p.id
        return bytesToHexString(id)
    }

    /**
     * 将字节数组转换为字符串
     */
    private fun bytesToHexString(inT: ByteArray): String {
        var i: Int
        var iny: Int
        val hex =
            arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
        var out = ""
        var j: Int = 0
        while (j < inT.size) {
            iny = inT[j].toInt() and 0xff
            i = iny shr 4 and 0x0f
            out += hex[i]
            i = iny and 0x0f
            out += hex[i]
            ++j
        }
        return out
    }

    //一般公家卡,扫描的信息
    private fun dumpTagData66(p: Parcelable,nfcBack: NFCBack): String {

        var tagIDHex: String = ""
        var tagIDDec: String = ""
        var tagIDSize: String = "1024"
        var msg = ""

        val sb = java.lang.StringBuilder()
        val tag = p as Tag
        val id = tag.id
        sb.append("Tag ID (hex): ").append(getHex(id)).append("\n")
        sb.append("Tag ID (dec): ").append(getDec(id)).append("\n")
        sb.append("ID (reversed): ").append(getReversed(id)).append("\n")
        val prefix = "android.nfc.tech."
        sb.append("Technologies: ")

        tagIDHex = getHex(id).toString()
        tagIDDec = getDec(id).toString()
        for (tech in tag.techList) {
            sb.append(tech.substring(prefix.length))
            sb.append(", ")
        }
        sb.delete(sb.length - 2, sb.length)
        for (tech in tag.techList) {
            if (tech == MifareClassic::class.java.name) {
                sb.append('\n')
                val mifareTag = MifareClassic.get(tag)
                tagIDSize = mifareTag.size.toString()
                var type = "Unknown"
                when (mifareTag.type) {
                    MifareClassic.TYPE_CLASSIC -> type = "Classic"
                    MifareClassic.TYPE_PLUS -> type = "Plus"
                    MifareClassic.TYPE_PRO -> type = "Pro"
                }
                sb.append("Mifare Classic type: ")
                sb.append(type)
                sb.append('\n')
                sb.append("Mifare size: ")
                sb.append("${mifareTag.size} bytes")
                sb.append('\n')
                sb.append("Mifare sectors: ")
                sb.append(mifareTag.sectorCount)
                sb.append('\n')
                sb.append("Mifare blocks: ")
                sb.append(mifareTag.blockCount)
            }
            if (tech == MifareUltralight::class.java.name) {
                sb.append('\n')
                val mifareUlTag: MifareUltralight = MifareUltralight.get(tag)
                var type = "Unknown"
                when (mifareUlTag.type) {
                    MifareUltralight.TYPE_ULTRALIGHT -> type = "Ultralight"
                    MifareUltralight.TYPE_ULTRALIGHT_C -> type = "Ultralight C"
                }
                sb.append("Mifare Ultralight type: ")
                sb.append(type)
            }
        }
        msg = sb.toString()
        nfcBack.onSuc(NFCBean(tagIDHex,tagIDDec,tagIDSize,msg))
        return sb.toString()
    }

    private fun getHex(bytes: ByteArray): String? {
        val sb = StringBuilder()
        for (i in bytes.indices.reversed()) {
            val b = bytes[i].toInt() and 0xff
            if (b < 0x10) sb.append('0')
            sb.append(Integer.toHexString(b))
            if (i > 0) {
                sb.append(" ")
            }
        }
        return sb.toString()
    }

    private fun getDec(bytes: ByteArray): Long {
        var result: Long = 0
        var factor: Long = 1
        for (i in bytes.indices) {
            val value = bytes[i].toLong() and 0xffL
            result += value * factor
            factor *= 256L
        }
        return result
    }

    private fun getReversed(bytes: ByteArray): Long {
        var result: Long = 0
        var factor: Long = 1
        for (i in bytes.indices.reversed()) {
            val value = bytes[i].toLong() and 0xffL
            result += value * factor
            factor *= 256L
        }
        return result
    }

    /**
     * 跳转到NFC设置界面*/
    fun jumpNFC(){
        val setNfc = Intent(Settings.ACTION_NFC_SETTINGS)
        activity!!.startActivity(setNfc)
    }

    /**
     * 该设备是否支持NFC*/
    fun getNFC(context: Context): Boolean{
        val packageManager = context.packageManager
        return packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)
    }
}

http://www.kler.cn/a/400739.html

相关文章:

  • web——upload-labs——第十二关——%00截断
  • 【HCIP]——OSPF综合实验
  • 第6章详细设计 -6.7 PCB工程需求表单
  • 解决微信小程序自定义tabbar点击两次才能跳转
  • 第六节、Docker 方式部署指南 github 上项目 mkdocs-material
  • 【Mysql】Mysql函数(上)
  • C#WPF的App.xaml启动第一个窗体的3种方式
  • 记录一下在原有的接口中增加文件上传☞@RequestPart
  • java基础面试题笔记(基础篇)
  • 基于YOLOv8深度学习的医学影像甲状腺结节病症检测诊断研究与实现(PyQt5界面+数据集+训练代码)
  • 周报(9)<仅供自己学习>
  • 前端网络性能优化问题
  • 【Go】-bufio库解读
  • Vue3-02
  • 微信小程序自定义tabbar的实现
  • Ekman理论回归
  • Spring Cloud Gateway 网关
  • 【MySQL 保姆级教学】事务的隔离级别(详细)--下(14)
  • c#中通过自定义Converter实现定制DateTime的序列化格式
  • SQL MID() 函数详解
  • TCP协议(三)
  • C#编写的日志记录组件 - 开源研究系列文章
  • git push时报错! [rejected] master -> master (fetch first)error: ...
  • Redis 安全
  • 统信UOS开发环境支持Golang
  • VRRP HSRP GLBP 三者区别