码迷,mamicode.com
首页 > 其他好文 > 详细

读写NFC标签中的Uri

时间:2015-05-17 13:41:00      阅读:288      评论:0      收藏:0      [点我收藏+]

标签:

 

 

技术分享
 1 // 从NdefRecord对象中解析出实际的Uri
 2 public class UriRecord {
 3     public static final Map<Byte, String> URI_PREFIX_MAP = new HashMap<Byte, String>();// 映射Uri前缀和对应的值
 4     static {
 5         // 设置NDEF Uri规范支持的Uri前缀,在解析payload时,在解析payload时,需根据payload的第1个字节定位相应的Uri前缀
 6         URI_PREFIX_MAP.put((byte) 0x00, "");
 7         URI_PREFIX_MAP.put((byte) 0x01, "http://www.");
 8         URI_PREFIX_MAP.put((byte) 0x02, "https://www.");
 9         URI_PREFIX_MAP.put((byte) 0x03, "http://");
10         URI_PREFIX_MAP.put((byte) 0x04, "https://");
11         URI_PREFIX_MAP.put((byte) 0x05, "tel:");
12         URI_PREFIX_MAP.put((byte) 0x06, "mailto:");
13         URI_PREFIX_MAP.put((byte) 0x07, "ftp://anonymous:anonymous@");
14         URI_PREFIX_MAP.put((byte) 0x08, "ftp://ftp.");
15         URI_PREFIX_MAP.put((byte) 0x09, "ftps://");
16         URI_PREFIX_MAP.put((byte) 0x0A, "sftp://");
17         URI_PREFIX_MAP.put((byte) 0x0B, "smb://");
18         URI_PREFIX_MAP.put((byte) 0x0C, "nfs://");
19         URI_PREFIX_MAP.put((byte) 0x0D, "ftp://");
20         URI_PREFIX_MAP.put((byte) 0x0E, "dav://");
21         URI_PREFIX_MAP.put((byte) 0x0F, "news:");
22         URI_PREFIX_MAP.put((byte) 0x10, "telnet://");
23         URI_PREFIX_MAP.put((byte) 0x11, "imap:");
24         URI_PREFIX_MAP.put((byte) 0x12, "rtsp://");
25         URI_PREFIX_MAP.put((byte) 0x13, "urn:");
26         URI_PREFIX_MAP.put((byte) 0x14, "pop:");
27         URI_PREFIX_MAP.put((byte) 0x15, "sip:");
28         URI_PREFIX_MAP.put((byte) 0x16, "sips:");
29         URI_PREFIX_MAP.put((byte) 0x17, "tftp:");
30         URI_PREFIX_MAP.put((byte) 0x18, "btspp://");
31         URI_PREFIX_MAP.put((byte) 0x19, "btl2cap://");
32         URI_PREFIX_MAP.put((byte) 0x1A, "btgoep://");
33         URI_PREFIX_MAP.put((byte) 0x1B, "tcpobex://");
34         URI_PREFIX_MAP.put((byte) 0x1C, "irdaobex://");
35         URI_PREFIX_MAP.put((byte) 0x1D, "file://");
36         URI_PREFIX_MAP.put((byte) 0x1E, "urn:epc:id:");
37         URI_PREFIX_MAP.put((byte) 0x1F, "urn:epc:tag:");
38         URI_PREFIX_MAP.put((byte) 0x20, "urn:epc:pat:");
39         URI_PREFIX_MAP.put((byte) 0x21, "urn:epc:raw:");
40         URI_PREFIX_MAP.put((byte) 0x22, "urn:epc:");
41         URI_PREFIX_MAP.put((byte) 0x23, "urn:nfc:");
42     }
43 
44     private final Uri mUri;
45 
46     private UriRecord(Uri uri) {
47         this.mUri = uri;
48     }
49 
50     // 获取已解析出的Uri
51     public Uri getUri() {
52         return mUri;
53     }
54 
55     // 分析NdefRecord对象中的payload,并创建封装Uri的UriRecord对象
56     public static UriRecord parse(NdefRecord record) {
57         short tnf = record.getTnf();
58         // TNF是TNF_WELL_KNOWN,也就是使用了Uri前缀
59         if (tnf == NdefRecord.TNF_WELL_KNOWN) {
60             return parseWellKnown(record);
61         }// TNF是TNF_ABSOLUTE_URI,也就是绝对Uri(不使用Uri前缀)
62         else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
63             return parseAbsolute(record);
64         }
65         throw new IllegalArgumentException("Unknown TNF " + tnf);
66     }
67 
68     // 分析绝对Uri
69     private static UriRecord parseAbsolute(NdefRecord record) {
70         byte[] payload = record.getPayload();
71         Uri uri = Uri.parse(new String(payload, Charset.forName("UTF-8")));// 直接将payload转成Uri
72         return new UriRecord(uri);
73     }
74 
75     // 处理已知类型的Uri,即使用Uri前缀形式表示的Uri
76     private static UriRecord parseWellKnown(NdefRecord record) {
77         // 判断RTD是否为RTD_URI
78         if (!Arrays.equals(record.getType(), NdefRecord.RTD_URI))
79             return null;
80         byte[] payload = record.getPayload();
81 
82         // payload[0]包含URI标识代码,即URI_PREFIX_MAP中的key,payload[1]…payload[payload.length-1]包含Uri的其余部分URI。
83         String prefix = URI_PREFIX_MAP.get(payload[0]);// 根据Uri标识代码获取Uri前缀
84         byte[] prefixBytes = prefix.getBytes(Charset.forName("UTF-8"));// 获取Uri前缀占用的字节数
85         byte[] fullUri = new byte[prefixBytes.length + payload.length - 1];// 为容纳完整的Uri创建一个byte数组
86         // 下面两行代码将Uri前缀和Uri的其余部分组合,形成一个完整的Uri
87         System.arraycopy(prefixBytes, 0, fullUri, 0, prefixBytes.length);
88         System.arraycopy(payload, 1, fullUri, prefixBytes.length,
89                 payload.length - 1);
90         Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));// 根据解析出来的Uri创建Uri对象
91         return new UriRecord(uri);// 创建UriRecord对象并返回
92     }
93 }
UriRecord.java
技术分享
 1 // 显示NFC标签中的Uri
 2 public class ShowNFCTagContentActivity extends Activity {
 3     private TextView mTagContent;
 4     private Tag mDetectedTag;
 5     private String mTagText;
 6 
 7     @Override
 8     public void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.activity_show_nfctag_content);
11         mTagContent = (TextView) findViewById(R.id.textview_tag_content);
12         mDetectedTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
13         Ndef ndef = Ndef.get(mDetectedTag);
14         mTagText = ndef.getType() + "\n最大数据容量:" + ndef.getMaxSize()
15                 + " bytes\n\n";
16         readNFCTag();
17         mTagContent.setText(mTagText);
18     }
19 
20     // 读取NFC标签中的数据
21     private void readNFCTag() {
22         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
23 
24             Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(
25                     NfcAdapter.EXTRA_NDEF_MESSAGES);
26 
27             NdefMessage ndefMessage = null;
28             int contentSize = 0;
29             if (rawMsgs != null) {
30 
31                 if (rawMsgs.length > 0) {
32                     ndefMessage = (NdefMessage) rawMsgs[0];// 只取第一个NdefMessage对象
33                     contentSize = ndefMessage.toByteArray().length;// 获取NFC标签存储的数据占用的大小(bytes)
34                 } else {
35                     return;
36                 }
37             }
38             try {
39                 NdefRecord record = ndefMessage.getRecords()[0];// 取第1个NdefMessage对象的第1个NdefRecord对象
40                 UriRecord uriRecord = UriRecord
41                         .parse(ndefMessage.getRecords()[0]);// 分析NdefRecord对象中的数据,并创建了UriRecord对象
42                 mTagText += uriRecord.getUri().toString() + "\n\nUri\n"
43                         + contentSize + " bytes";// 获取Uri等信息,这些信息会显示在当前窗口上
44             } catch (Exception e) {
45                 mTagContent.setText(e.getMessage());
46             }
47         }
48     }
49 }
ShowNFCTagContentActivity.java
技术分享
<activity
    android:name=".ReadWriteUriMainActivity"
    android:label="读写NFC标签的Uri"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <!-- 下面的配置能检测到http、https和ftp协议的NDEF Uri格式的NFC标签,无法识别其他协议的NFC标签。当然也可添加更多的Uri协议 -->
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:scheme="ftp" />
    </intent-filter>
</activity>
AndroidManifest.xml

注意:

  • 由于本例是直接在AndroidManifest.xml文件中指定了NFC的相关Action,故即使程序退出,这些Action仍然会起作用。这时系统就不会再使用默认的NFC处理程序来处理NDEF Uri格式的NFC标签了,除非卸载这些程序。
  • 本例实现的ReadWriteUriMainActivity.createUriRecord方法与NdefRecord.createUri方法的实现原理类似,都使用了一个Uri前缀与相应的标识代码的映射,利用这个映射将实际的Uri前缀转换成用字节表示的标识代码(可自行查看NdefRecord.createUri方法的源代码)。

读写NFC标签中的Uri

标签:

原文地址:http://www.cnblogs.com/qq1274540609/p/4509402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!