NFC是Near Field Communication的缩写,也就是近场通信,是一种短距离数据传输技术,该功能相对于传统的蓝牙以及红外等数据传输功能各有利弊,是目前主流的近距离通信技术之一。NFC 提供了一种简单、触控式的解决方案,可以让手机用户简单直观地交换信息、访问内容与服务。
1、配置nfc的使用权限:
1
2
3
4<uses-permission android:name="android.permission.NFC"/> <uses-feature android:name="android.hardware.nfc" android:required="true" /> //设置MainActivity的启动方式 android:launchMode="SingleTop"
2、Nfc有三层的过滤机制:
1
2
31、ACTION_NDEF_DISCOVERED 2、ACTION_TECH_DISCOVERED 3、ACTION_TAG_DISCOVERED
Android按顺序匹配三层过滤机制的流程如下:
声明过滤机制:
1
2
3
4
5
6
7<intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech" /> </activity>
使用TECH_DISCOVERED的过滤规则需先在/res/xml下面创建一个过滤规则文件,这个里面定义的是nfc实现的各种标准,每一个nfc卡都会符合多个不同的标准。
以下是在nfc_tech.xml定义的多种检测标准:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<tech-list> <tech>android.nfc.tech.MifareClassic</tech> </tech-list> <tech-list> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> <tech-list> <tech>android.nfc.tech.IsoDep</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcA</tech> </tech-list> <tech-list> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NfcB</tech> </tech-list> //可以在一个<tech-list></tech-list>组中定义多个标准,如最后一组
以上是使用nfc前的一些配置信息。
3、获取NfcAdapeter适配器
1
2
3
4
5
6
7
8
9
10//获取Nfc适配器,判断设备是否支持nfc mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if(mNfcAdapter==null){ Toast.makeText(this, "该设备比支持nfc", Toast.LENGTH_SHORT).show(); return; } if(!mNfcAdapter.isEnabled()){ Toast.makeText(this, "先打开nfc功能", Toast.LENGTH_SHORT).show(); return; }
4、因为设置的启动方式是”SingleTop”,在手机检测到有nfc标签时,系统会给当前的activity发送一个intent,就会调用onNewIntent(Intent intent)的方法,所以重写该方法,在该方法中对nfc标签进行解析。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21protected void onNewIntent(Intent intent) { // TODO 自动生成的方法存根 super.onNewIntent(intent); //判断发来的intent是否我们设置的过滤机制,不是则退出不做处理 if (!NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) { return; } //获取到Tag标签对象 tag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if(tag!=null){ //Tag标签中的Ndef内容 ndef = Ndef.get(tag); }else{ return; } //获取此标签中支持的技术 String[] techList=tag.getTechList(); for (String tech:techList){ Log.d("TECH",tech); } }
同时需要在onResume()和onPause()设置对nfc标签的连接的监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19PendingIntent pend = PendingIntent.getActivity(this, 0, new Intent(this, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); //开始监听nfc功能 protected void onResume() { // TODO 自动生成的方法存根 super.onResume(); if (mNfcAdapter != null) { //开始监听NFC设备是否连接,如果连接就发pend意图,设置当前程序为优先处理nfc的程序 mNfcAdapter.enableForegroundDispatch(this, pend, null, null); } } //停止监听nfc protected void onPause() { // TODO 自动生成的方法存根 super.onPause(); if (mNfcAdapter != null) { mNfcAdapter.disableForegroundDispatch(this); } }
5、解析卡片的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44//获取卡片的ID tag.getId(); //可将以下方法将ID转换成16进制码 private String bytesToHexString(byte[] bArray) { StringBuffer strBuf = new StringBuffer(bArray.length); String strTemp; for(int i = 0; i < bArray.length; i++) { strTemp = Integer.toHexString(0xFF & bArray[i]); if(strTemp.length() < 2) { strBuf.append(0); } strBuf.append(strTemp.toUpperCase()); } return strBuf.toString(); } //获取卡片类型 String[] techList = tag.getTechList(); //NFC卡的类型: Mifare Classic/UltraLight Info/IsoDep for (int i = 0; i < techList.length; i++) { //根据不同的卡片类型获取各自的Tag if (techList[i].equals(NfcA.class.getName())) { NfcA nfc = NfcA.get(tag); try { if ("".equals(type)) Log.d("Type",NfcA.class.getName()); } catch (Exception e) { e.printStackTrace(); } } else if (techList[i].equals(MifareUltralight.class.getName())) { MifareUltralight mifareUlTag = MifareUltralight .get(tag); switch (mifareUlTag.getType()) { case MifareUltralight.TYPE_ULTRALIGHT: Log.d("Type","ULTRALIGHT"); break; case MifareUltralight.TYPE_ULTRALIGHT_C: Log.d("Type","ULTRALIGHT_C"); break; } }else if(techList[i].equals(IsoDep.class.getName())){ Log.d("Type",IsoDep.class.getName()); } }
6、读取卡片的内容:卡片的内容主要是这三种类型:1、文本类型,2、应用程序类型,3、Uri链接类型
应用程序跟Uri链接类型在andriod检测到nfc标签时可以快速启动程序或打开网页。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38private void readIntent(){ if (tag == null) { return; } if(ndef==null){ return; } try { //打开连接 ndef.connect(); //读取标签中的ndef内容 NdefMessage message = ndef.getNdefMessage(); //获取标签中的内容长度 int length = message.getByteArrayLength(); if(message==null){ Toast.makeText(this, "Null Message", Toast.LENGTH_SHORT).show(); ndef.close(); return; } //一个NdefMessage是有一条或多条的NdefRecord组成。 NdefRecord[] recoder = message.getRecords(); for(NdefRecord r:recoder){ //使用该方法获取该NdefRecord中的实际内容 byte[] b = r.getPayload(); //如果直接使用r.toString()获取到的内容还包括了ndef格式中的一些前缀数据 } //将消息转换成字节数组 //关闭连接 ndef.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (FormatException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } }
7、往标签中写入数据,上一节说到nfc的内容有主要是三种类型,不同的数据类型对应着不同的写入方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57//文本类型 NdefRecord recordText=new NdefRecord(NdefRecord.TNF_WELL_KNOWN,NdefRecord.RTD_TEXT, new byte[]{0},"Hello World!".getBytes(Charset.forName("utf-8"))); //应用程序类型 NdefRecord recordPack=NdefRecord.createApplicationRecord(packageName); //packageName是程序包名,可通过下面的方法获取系统中所有程序的包名 PackageManager manager = getPackageManager(); List<PackageInfo> packageInfos = manager.getInstalledPackages(PackageManager.GET_ACTIVITIES); String[] mPackage = new String[packageInfos.size()];; //遍历 int i=0; for (PackageInfo pi : packageInfos) { //获取软件名和包名 mPackage[i] = pi.applicationInfo.loadLabel(manager)+"n"+pi.packageName; i++; } //Uri类型 NdefRecord recordUri = NdefRecord.createUri(Uri.parse("www.baidu.com")); //创建NdefMessage,并将以上的NdefRecord添加进来,写入的NdefRecord可以是任意一条,也可以是多条 NdefMessage message = new NdefMessagge(new NdefRecord[]{recordText,recordPack,recordUri); //将NdefMessage写进标签中 //获得写入大小 int size = ndefMessage.toByteArray().length; //判断是否是NDEF标签 try { if(ndef != null) { //说明是NDEF标签,开始连接 ndef.connect(); //判断是否可写 if(!ndef.isWritable()){ Toast.makeText(this, "当前设备不支持写入",Toast.LENGTH_LONG).show(); ndef.close(); return; } //获取标签的容量大小,判断是否足够写入 if(ndef.getMaxSize() < size){ Toast.makeText(this, "容量不足",Toast.LENGTH_LONG).show(); ndef.close(); return; } //写入 try { //使用该方法将ndefmessage写进标签 ndef.writeNdefMessage(ndefMessage); Toast.makeText(this, "写入成功",Toast.LENGTH_LONG).show(); ndef.close(); } catch (FormatException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); }
以上就是在安卓系统上的nfc功能的使用,可以通过设置标签的内容实现某种功能,如将某一应用程序的包名写进标签,在标签靠近安卓板后,系统会自动打开该应用程序。
最后
以上就是精明冥王星最近收集整理的关于安卓之Nfc的使用的全部内容,更多相关安卓之Nfc内容请搜索靠谱客的其他文章。
发表评论 取消回复