android nfc常用标签读取

随着nfc智能手机越来越普及,nfc在生活中的应用也越来越多,加上最近自己也正好有点时间,因此打算研究一下nfc标签的读取,在网上找了一些资料,很多文章都写的很好,不过都是针对某种特定数据格式的nfc标签的读写,也由各种nfc的app可以读取各种类型的nfc标签,但是又没有源码,由此,本文主要是针对常用的nfc标签做基本读取操作,第一次发文章,如果有问题请大家指正。

nfc的基本介绍就不做说明了,网上有很多资料,下面主要描述nfc数据过滤、NDEF数据读取和非NDEF数据读取:

1、nfc数据过滤

      nfc主要有三种过滤器,分别是NDEF_DISCOVERED,TECH_DISCOVERED,TAG_DISCOVERED,主要说明如下:

      NDEF_DISCOVERED:当检测到标签中含有NDEF格式的数据,并且在应用中声明了可以接收ndef数据的intent时,触发该action的intent;

      TECH_DISCOVERED:当没有应用响应NDEF_DISCOVERED时,会发出tech的intent;

      TAG_DISCOVERED:当前两个intent都没有触发时,默认触发tag类型的intent;

      (1) NDEF_DISCOVERED过滤定义:

<intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                 <data android:scheme="http"
              android:host="developer.android.com"
              android:pathPrefix="/index.html" />
            </intent-filter>
     (2)TECH_ DISCOVERED过滤定义:

 <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />

nfc_tech_filter文件:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
	<tech-list>
		<tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.NfcF</tech>
        <tech>android.nfc.tech.NfcV</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
	</tech-list>
</resources>

(3) TAG_ DISCOVERED过滤:

 <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED" />
            </intent-filter>

2、各类nfc数据读取

(1)NDEF数据读取

          TNF_ABSOLUTE_URI读取:

  

private void parseAbsoluteUriRecode(NdefRecord record) {
		byte[] payload = record.getPayload();
		Uri uri = Uri.parse(new String(payload, Charset.forName("utf-8")));
		setNoteBody(new String(payload, Charset.forName("utf-8")));
	}

<span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">        TNF_WELL_KNOWN的URI读取:</span>

<pre name="code" class="java">private void parseWellKnownUriRecode(NdefRecord record) {
		Preconditions.checkArgument(Arrays.equals(record.getType(),
				NdefRecord.RTD_URI));
		byte[] payload = record.getPayload();
		String prefix = URI_PREFIX_MAP.get(payload[0]);
		byte[] fulluri = Bytes.concat(
				prefix.getBytes(Charset.forName("utf-8")),
				Arrays.copyOfRange(payload, 1, payload.length));
		Uri uri = Uri.parse(new String(fulluri, Charset.forName("utf-8")));
		setNoteBody(new String(fulluri, Charset.forName("utf-8")));
	}

        TNF_WELL_KNOWN的TEXT读取: 

private void parseWellKnownTextRecode(NdefRecord record) {
		Preconditions.checkArgument(Arrays.equals(record.getType(),
				NdefRecord.RTD_TEXT));
		String payloadStr = "";
		byte[] payload = record.getPayload();
		Byte statusByte = record.getPayload()[0];
		String textEncoding = "";
		textEncoding = ((statusByte & 0200) == 0) ? "utf-8" : "utf-16";
		int languageCodeLength = 0;
		languageCodeLength = statusByte & 0077;
		try {
			payloadStr = new String(payload, languageCodeLength + 1,
					payload.length - languageCodeLength - 1, textEncoding);
		} catch (UnsupportedEncodingException e) {
		}
		setNoteBody(payloadStr);
	}

    TNF_ABSOLUTE_URI的record类型和TNF_EXTERNAL_TYPE类型读取:

private void parseOtherRecode(NdefRecord record) {
		byte[] payload = record.getPayload();
		Uri uri = Uri.parse(new String(payload, Charset.forName("utf-8")));
		setNoteBody(new String(payload, Charset.forName("utf-8")));
	}
(2)非NDEF数据读取

MifareUltralight读取:

public String readTagUltralight(Tag tag) {
		MifareUltralight mifare = MifareUltralight.get(tag);
		try {
			mifare.connect();
			int size=mifare.PAGE_SIZE;
			byte[] payload = mifare.readPages(0);
			String result="page1:"+ByteArrayToHexString(payload)+"\n"+"总容量:"+String.valueOf(size)+"\n";

			//这里只读取了其中几个page、
			byte[] payload1 = mifare.readPages(4);
			byte[] payload2 = mifare.readPages(8);
			byte[] payload3 = mifare.readPages(12);
			result+="page4:"+ByteArrayToHexString(payload1)+"\npage8:"+ByteArrayToHexString(payload2)+"\npage12:"+ByteArrayToHexString(payload3)+"\n";
			
			//byte[] payload4 = mifare.readPages(16);
			//byte[] payload5 = mifare.readPages(20);
			return result;
					//+ new String(payload4, Charset.forName("US-ASCII"));
					//+ new String(payload5, Charset.forName("US-ASCII"));
		} catch (IOException e) {
			Log.e(TAG, "IOException while writing MifareUltralight message...",
					e);
			return "读取失败!";
		} catch (Exception ee) {
			Log.e(TAG, "IOException while writing MifareUltralight message...",
					ee);
			return "读取失败!";
		} finally {
			if (mifare != null) {
				try {
					mifare.close();
				} catch (IOException e) {
					Log.e(TAG, "Error closing tag...", e);
				}
			}
		}
	}

MifareClassic读取:

public String readTagClassic(Tag tag) {
		boolean auth = false;
		MifareClassic mfc = MifareClassic.get(tag);
		// 读取TAG
		try {
			String metaInfo = "";
			int type = mfc.getType();// 获取TAG的类型
			int sectorCount = mfc.getSectorCount();// 获取TAG中包含的扇区数
			String typeS = "";
			switch (type) {
			case MifareClassic.TYPE_CLASSIC:
				typeS = "TYPE_CLASSIC";
				break;
			case MifareClassic.TYPE_PLUS:
				typeS = "TYPE_PLUS";
				break;
			case MifareClassic.TYPE_PRO:
				typeS = "TYPE_PRO";
				break;
			case MifareClassic.TYPE_UNKNOWN:
				typeS = "TYPE_UNKNOWN";
				break;
			}
			metaInfo += "卡片类型:" + typeS + "\n共" + sectorCount + "个扇区\n共"
					+ mfc.getBlockCount() + "个块\n存储空间: " + mfc.getSize()
					+ "B\n";
			for (int j = 0; j < sectorCount; j++) {
				// Authenticate a sector with key A.

				auth = mfc.authenticateSectorWithKeyA(j,
						MifareClassic.KEY_DEFAULT);
				int bCount;
				int bIndex;
				if (auth) {
					metaInfo += "Sector " + j + ":验证成功\n";
					// 读取扇区中的块
					bCount = mfc.getBlockCountInSector(j);
					bIndex = mfc.sectorToBlock(j);
					for (int i = 0; i < bCount; i++) {
						byte[] data = mfc.readBlock(bIndex);
						metaInfo += "Block " + bIndex + " : "
								+ ByteArrayToHexString(data) + "\n";
						bIndex++;
					}
				} else {
					metaInfo += "Sector " + j + ":验证失败\n";
				}
			}
			return metaInfo;
		} catch (Exception e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
			e.printStackTrace();
		} finally {
			if (mfc != null) {
				try {
					mfc.close();
				} catch (IOException e) {
					Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG)
							.show();
				}
			}
		}
		return null;

	}

IsoDep读取:

IsoDep isodep = IsoDep.get(tagFromIntent);
					isodep.connect();
					//select the card manager applet
					byte[] mf = { (byte) '1', (byte) 'P',
							(byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y',
							(byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F',
							(byte) '0', (byte) '1', };
	                String result="";
					byte[] mfRsp = isodep.transceive(getSelectCommand(mf));
					Log.d(TAG, "mfRsp:" + HexToString(mfRsp));
					//select Main Application
					byte[] wht = { (byte) 0x41, (byte) 0x50,//此处以武汉通为例,其它的卡片参考对应的命令,网上可以查到
							(byte) 0x31, (byte) 0x2E, (byte) 0x57, (byte) 0x48, (byte) 0x43,
							(byte) 0x54, (byte) 0x43, };
		            byte[] sztRsp = isodep.transceive(getSelectCommand(wht));

		            byte[] balance = { (byte) 0x80, (byte) 0x5C, 0x00, 0x02, 0x04};
		            byte[] balanceRsp = isodep.transceive(balance);
		            Log.d(TAG, "balanceRsp:" + HexToString(balanceRsp));
		            if(balanceRsp!=null && balanceRsp.length>4)
		            {
		            	int cash = byteToInt(balanceRsp, 4);	            	
		            	float ba = cash / 100.0f;
		            	result+="  余额:"+String.valueOf(ba);
		            	 
		            }
		            setNoteBody(result); 
		            isodep.close();               

NfcB读取:

nfcbTag = NfcB.get(tag);
			try {
				nfcbTag.connect();
				if (nfcbTag.isConnected()) {
					System.out.println("已连接");
					Toast.makeText(MainActivity.this, "身份证已连接",
							Toast.LENGTH_SHORT).show();
					new CommandAsyncTask().execute();

				}
				// nfcbTag.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

NfcA读取:

 NfcA nfca = NfcA.get(tagFromIntent);
           try{
               nfca.connect();
               if (nfca.isConnected()) {//NTAG216的芯片
               byte[] SELECT = {
                       (byte) 0x30,
                       (byte) 5 & 0x0ff,//0x05
                   };
               byte[] response = nfca.transceive(SELECT);
               nfca.close();
               if(response!=null){
               setNoteBody(new String(response, Charset.forName("utf-8")));
               }
               }
           }
           catch(Exception e){
           }

NfcF读取:

NfcF nfc = NfcF.get(tag);
           try {
               nfc.connect();
               byte[] felicaIDm = new byte[]{0};
               byte[] req = readWithoutEncryption(felicaIDm, 10);
               byte[] res = nfc.transceive(req);
               nfc.close();
               setNoteBody(ByteArrayToHexString(res));
           } catch (Exception e) {
               Log.e(TAG, e.getMessage() , e);
           }

NfcV读取:

NfcV tech = NfcV.get(tag);
    	    if (tech != null) {
    	    	try {
    	    		tech.connect();
                    if (tech.isConnected()) {
                    	byte[] tagUid = tag.getId();  // store tag UID for use in addressed commands

                    	int blockAddress = 0;
                    	int blocknum = 4;
                    	byte[] cmd = new byte[] {
                    	        (byte)0x22,  // FLAGS
                    	        (byte)0x23,  // 20-READ_SINGLE_BLOCK,23-所有块
                    	        0, 0, 0, 0, 0, 0, 0,0,
                    	        (byte)(blockAddress & 0x0ff),(byte)(blocknum-1 & 0x0ff)
                    	};
                    	System.arraycopy(tagUid, 0, cmd, 2, tagUid.length);  // paste tag UID into command
                    	
                    	byte[] response = tech.transceive(cmd);
                        tech.close();
                        if(response!=null){
                        setNoteBody(new String(response, Charset.forName("utf-8")));
                        }
                    }
                } catch (IOException e) {
                   
                }
    	    }

Ndef与NdefFormatable读取:

NdefMessage[] messages = getNdefMessages(getIntent());
           byte[] payload = messages[0].getRecords()[0].getPayload();
           setNoteBody(new String(payload));
NdefMessage[] getNdefMessages(Intent intent) {//读取nfc数据
        // Parse the intent
    	
        NdefMessage[] msgs = null;
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMsgs != null) {
                msgs = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    msgs[i] = (NdefMessage) rawMsgs[i];
                }
            } else {
                // Unknown tag type
                byte[] empty = new byte[] {};
                NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
                NdefMessage msg = new NdefMessage(new NdefRecord[] {
                    record
                });
                msgs = new NdefMessage[] {
                    msg
                };
            }
        } else {
            Log.d(TAG, "Unknown intent.");
            finish();
        }
        return msgs;
    }
	


最后提供一下源代码下载地址:http://download.csdn.net/detail/shjn2004/9610180

       

       


  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值