Android中读取NFC标签卡中的ID

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Android中读取NFC标签卡中的ID,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

场景

APP中读取NFC卡中的标签ID,作为用户的唯一标识进行登录验证。

首先需要确保手机支持NFC功能。其次具备一张NFC卡片。

读取id就是利用的读卡器模式,当把卡片靠近手机的NFC天线的时候,NFC会识别到卡,

然后把卡对象装到intent里面,

并发送广播NfcAdapter.ACTION_TECH_DISCOVERED,

应用程序接到这个广播之后,通过intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)来获取到卡对象,

然后就可以对卡进行读写

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi 
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、新建项目,添加权限

打开Android Studio新建一个项目,在AndroidManifest.xml中添加权限。

    <!--    NFC所需权限-->
    <uses-permission android:name="android.permission.NFC" />
    <!-- 要求当前设备必须要有NFC芯片 -->
    <uses-feature android:name="android.hardware.nfc" android:required="true" />

Android中读取NFC标签卡中的ID

2、将要读取NFC的Activity设置为singleTop

这里是在MainActivity中

        <activity android:name=".MainActivity" android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Android中读取NFC标签卡中的ID

Activity共有四种启动模式:

standard

标准模式,也是Activity的默认启动模式,允许存在多个Activity实例,

每次启动页面时都会生成一个新的Activity实例。

singleTop

相比于standard,有新的页面启动请求时,当目标Activity处于当前栈顶时,

会调用Activity的onNewIntent()方法,但不创建新实例;其他情况都和standard一致。

其他两种不做介绍。

NFC检测到对象时,会在系统startActivity,那么目标activity已经是启动了,

所以我们需要在onNewIntent方法中接受tag对象,同时activity启动模式设为singleTop或singleTask也为了避免重复创建实例

3、设计页面布局

打开activity_main.xml,修改如下

​
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#151414"
    >
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_centerInParent="true"
        >
        <TextView
            android:layout_width="wrap_content"
            android:text="读取到的卡UID: "
            android:textColor="#fff"
            android:layout_height="wrap_content" />
        <TextView
            android:textColor="#fff"
            android:id="@+id/tv_uid"
            android:text="                            "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</RelativeLayout>

​

4、修改Activity

在OnCreate方法中,获取NfcAdapter实例,然后获取通知,判断支持NFC并且打开后,当获取通知后会调用onNewIntent方法。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //获取显示文本框
        tvUid = (TextView) findViewById(R.id.tv_uid);
        //获取NfcAdapter实例
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        //获取通知
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        //如果获取不到则不支持NFC
        if (nfcAdapter == null) {
            Toast.makeText(MainActivity.this,"设备不支持NFC",Toast.LENGTH_LONG).show();
            return;
        }
        //如果获取到的为不可用状态则未启用NFC
        if (nfcAdapter!=null&&!nfcAdapter.isEnabled()) {
            Toast.makeText(MainActivity.this,"请在系统设置中先启用NFC功能",Toast.LENGTH_LONG).show();
            return;
        }
        //因为启动模式是singleTop,于是会调用onNewIntent方法
        onNewIntent(getIntent());

    }

在onNewIntent中,解析intent携带的卡对象

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        //获取、传递、解析intent对象,intent中携带卡对象
        resolveIntent(intent);
    }

    //解析intent
    void resolveIntent(Intent intent) {
        //获取intent中携带的标签对象
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (tag != null) {
            //处理标签对象
            processTag(intent);
        }
    }

在处理标签对象的方法中获取携带的数据中的ID字节数组并转换成十六进制字符串显示。

    //处理tag
    public void processTag(Intent intent) {
        //获取到卡对象
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        //获取卡id这里即uid,字节数组类型
        byte[] aa = tagFromIntent.getId();
        //字节数组转十六进制字符串
        String str = ByteArrayToHexString(aa);
        tvUid.setText(str);

    }

完整Activity代码

package com.badao.nfcdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {


    private NfcAdapter nfcAdapter;
    private PendingIntent pendingIntent;
    private TextView tvUid;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //获取显示文本框
        tvUid = (TextView) findViewById(R.id.tv_uid);
        //获取NfcAdapter实例
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        //获取通知
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        //如果获取不到则不支持NFC
        if (nfcAdapter == null) {
            Toast.makeText(MainActivity.this,"设备不支持NFC",Toast.LENGTH_LONG).show();
            return;
        }
        //如果获取到的为不可用状态则未启用NFC
        if (nfcAdapter!=null&&!nfcAdapter.isEnabled()) {
            Toast.makeText(MainActivity.this,"请在系统设置中先启用NFC功能",Toast.LENGTH_LONG).show();
            return;
        }
        //因为启动模式是singleTop,于是会调用onNewIntent方法
        onNewIntent(getIntent());

    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        //获取、传递、解析intent对象,intent中携带卡对象
        resolveIntent(intent);
    }

    //解析intent
    void resolveIntent(Intent intent) {
        //获取intent中携带的标签对象
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        if (tag != null) {
            //处理标签对象
            processTag(intent);
        }
    }

    //字节数组转换十六进制
    private 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" };
        String out = "";
        for (j = 0; j < inarray.length; ++j) {
            in = (int) inarray[j] & 0xff;
            i = (in >> 4) & 0x0f;
            out += hex[i];
            i = in & 0x0f;
            out += hex[i];
        }
        return out;
    }


    //处理tag
    public void processTag(Intent intent) {
        //获取到卡对象
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        //获取卡id这里即uid,字节数组类型
        byte[] aa = tagFromIntent.getId();
        //字节数组转十六进制字符串
        String str = ByteArrayToHexString(aa);
        tvUid.setText(str);

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (nfcAdapter != null)
            //设置程序不优先处理
            nfcAdapter.disableForegroundDispatch(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (nfcAdapter != null)
            //设置程序优先处理
            nfcAdapter.enableForegroundDispatch(this, pendingIntent,
                    null, null);
    }

}

5、运行app,打开nfc,将NFC卡片靠近手机

Android中读取NFC标签卡中的ID 

可以以debug模式运行,依次打断点查看效果

Android中读取NFC标签卡中的ID

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136178.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!