Android获取NFC标签和NFC十进制16进制ID

要获取NFC标签,首先需要添加NFC权限

<uses-feature

    android:name="android.hardware.nfc"

    android:required="true"/>

<uses-permission android:name="android.permission.NFC"/>

获取NFC标签及其ID

class NfcActivity : BaseActivity() {
    private lateinit var imgBack: ImageView
    private lateinit var mNfcAdapter: NfcAdapter
    private lateinit var mPendingIntent: PendingIntent
    //nfc标签信息
    private lateinit var tvNfcTag: TextView
    //nfc十进制ID
    private lateinit var tvNfcD: TextView
    //nfc16进制ID
    private lateinit var tvNfcH: TextView

    /**
     * 启动Activity
     */
    override fun onStart() {
        super.onStart()
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
        //一旦截获NFC消息,就会通过PendingIntent调用窗口
        mPendingIntent = PendingIntent.getActivity(this, 0, Intent(this, javaClass), 0)
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_nfc
    }

    override fun eventBus(event: Any?) {

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        imgBack = findViewById(R.id.img_nfc_back)
        tvNfcD = findViewById(R.id.tv_nfc_d)
        tvNfcH = findViewById(R.id.tv_nfc_h)
        tvNfcTag = findViewById(R.id.tv_nfc_tag)
        imgBack.setOnClickListener { finish() }
    }

    override fun onResume() {
        super.onResume()
        //设置处理优于所有其他NFC的处理
        mNfcAdapter.enableForegroundDispatch(
            this,
            mPendingIntent,
            null,
            null
        )
    }

    override fun onPause() {
        super.onPause()
        //恢复默认状态
        mNfcAdapter.disableForegroundDispatch(this)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        //        readFromTag(intent);
        readNfcTag(intent!!)

    }

    /**
     * 读取NFC标签文本数据
     */
    private fun readNfcTag(intent: Intent) {
        val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        if (tag != null) {
            val cardNo = flipHexStr(ByteArrayToHexString(tag.id)).toLong(16)
            tvNfcD.text = cardNo.toString()
            tvNfcH.text = ByteArrayToHexString(tag.id)
        }
        if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) {
            val rawMessages = intent.getParcelableArrayExtra(
                NfcAdapter.EXTRA_NDEF_MESSAGES
            )
            var msgs: Array<NdefMessage?>? = null
            var contentSize = 0
            if (rawMessages != null) {
                msgs = arrayOfNulls(rawMessages.size)
                for (i in rawMessages.indices) {
                    msgs[i] = rawMessages[i] as NdefMessage
                    contentSize += msgs[i]!!.toByteArray().size
                }
            }
            try {
                if (null != msgs) {
                    val record = msgs[0]!!.records[0]
                    val textRecord: String? =
                        NfcUtil.parseTextRecord(record)
                    Log.e("nfcTag-->", "" + textRecord)
                    tvNfcTag.text = textRecord
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Log.e("nfcError-->", "" + e)
            }
        }
    }
}

获取标签及其ID的工具类

public class NfcUtil {
    /**
     * 解析NDEF文本数据,从第三个字节开始,后面的文本数据
     * @param ndefRecord
     * @return
     */
    public static String parseTextRecord(NdefRecord ndefRecord) {
        /**
         * 判断数据是否为NDEF格式
         * 判断TNF
         */
        if (ndefRecord.getTnf() != NdefRecord.TNF_WELL_KNOWN) {
            return null;
        }
        //判断可变的长度的类型
        if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
            return null;
        }
        try {
            //获得字节数组,然后进行分析
            byte[] payload = ndefRecord.getPayload();
            //下面开始NDEF文本数据第一个字节,状态字节
            //判断文本是基于UTF-8还是UTF-16的,取第一个字节"位与"上16进制的80,16进制的80也就是最高位是1,
            //其他位都是0,所以进行"位与"运算后就会保留最高位
            String textEncoding = ((payload[0] & 0x80) == 0) ? "UTF-8" : "UTF-16";
            //3f最高两位是0,第六位是1,所以进行"位与"运算后获得第六位
            int languageCodeLength = payload[0] & 0x3f;
            //下面开始NDEF文本数据第二个字节,语言编码
            //获得语言编码
            String languageCode = new String(payload, 1, languageCodeLength, StandardCharsets.US_ASCII);
            //下面开始NDEF文本数据后面的字节,解析出文本
            String textRecord = new String(payload, languageCodeLength + 1,
                    payload.length - languageCodeLength - 1, textEncoding);
            return textRecord;
        } catch (Exception e) {
            throw new IllegalArgumentException();
        }
    }

    // 16转10进制
    public static String flipHexStr(String s) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i <= s.length() - 2; i = i + 2) {
            result.append(new StringBuilder(s.substring(i, i + 2)).reverse());
        }
        return result.reverse().toString();
    }


    public static String ByteArrayToHexString(byte[] inarray) {
        int i, j, in;
        String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
                "B", "C", "D", "E", "F"};
        StringBuilder out = new StringBuilder();


        for (j = 0; j < inarray.length; ++j) {
            in = (int) inarray[j] & 0xff;
            i = (in >> 4) & 0x0f;
            out.append(hex[i]);
            i = in & 0x0f;
            out.append(hex[i]);
        }
        return out.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值