NFC 读 取

NFC Tools 是一款应用程序,可让你在 NFC 标签和其他兼容的 NFC 芯片上读取、写入和编程任务。

简单,直观,NFC Tools可以在你的 NFC 标签上记录标准信息,这些信息将与任何 NFC 设备兼容。例如,你可以轻松存储你的联系方式、网址、电话号码、社交资料甚至位置。

而且该应用程序允许你在 NFC 标签上对任务进行编程,以便将以前你曾经枯燥重复的操作自动化。比如打开蓝牙、设置闹钟、控制音量、共享 WiFi 网络配置等等。

在睡觉前你只需要把你的手机靠近 NFC 标签,你的手机将切换到静音状态,你的闹钟将自动设置为第二天早上。很方便,不是吗?

如果你精通技术,你还可以使用极客、预设变量、条件和高级任务,以便你可以创建更复杂的操作。

200 多项可用任务和无限组合让你的生活更轻松。

将你的设备靠近“读取”选项卡上的 NFC 芯片,你可以查看以下数据:
- 制造商和标签类型(例如:Mifare Ultralight、NTAG215)。
- 标签的序列号(例如:04:85:c8:5a:40:2b:80)。
- 可用的技术和标签标准(例如:NFC A、NFC Forum Type 2)。
- 有关大小和内存的信息。
- 有关标签是可写的或被锁定的。
- 最后很重要的是,标签包含的所有数据(NDEF 记录)。

“写入”选项卡可让你记录标准化数据,例如:
- 一个简单的文本、一个网站链接、视频、社交资料或应用程序。
- 电子邮件、电话号码或预定义的短信。
- 联系信息或紧急联系人。
- 地址或地理位置。
- WiFi 或蓝牙配置。
- 和更多。

写入功能允许你添加任意数量的数据,这样你就可以在标签上记录大量信息。

“其他”选项卡下提供了其他功能,例如复制、擦除和密码保护您的 NFC 标签。

允许你把你的手机自动化的任务位于“任务”选项卡下,并已分类。

以下是一些可操作的示例:
- 激活、停用或切换你的蓝牙。
- 将声音配置文件配置为静音、振动或正常。
- 更改屏幕亮度。
- 设置音量级别(例如你的闹钟、通知或铃声音量)。
- 设置计时器或闹钟。
- 在你的日历中插入一个事件。
- 启动应用程序或 URL / URI。
- 发送短信或拨打某人的电话。
- 用文本到语音朗读文本。
- 配置 WiFi 网络。
- 和更多。

NFC 工具已使用以下 NFC 标签进行测试:
- NTAG 203、210、210u、212、213、213TT、215、216、413 DNA、424 DNA。
- Ultralight, Ultralight C, Ultralight EV1.
- ICODE SLI、SLI-S、SLIX、SLIX-S、SLIX-L、SLIX2、DNA。
- DESFire EV1, EV2, EV3, LIGHT.
- ST25TV、ST25TA、STLRI2K。
- 还有 Mifare Classic、Felica、Topaz、EM4x3x。

如果你有任何问题,请随时与我们联系,我们将很乐意为你提供帮助。

注意:
- 设备需要 具备NFC的 兼容性。
- 为了执行任务,你需要下载免费的应用程序:NFC Tasks。

场景

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

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

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

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

并发送广播NfcAdapter.ACTION_TECH_DISCOVERED,

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

然后就可以对卡进行读写

注:

博客:
//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" />

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>

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="//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卡片靠近手机

 

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

Toplist

最新的帖子

標籤