NFC技术:读写NFC标签中的Uri数据

Posted 张兮兮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NFC技术:读写NFC标签中的Uri数据相关的知识,希望对你有一定的参考价值。

 1 public class UriRecord {
 2     public static final Map<Byte, String> URI_PREFIX_MAP = new HashMap<Byte, String>();
 3     static {
 4         URI_PREFIX_MAP.put((byte) 0x00, "");
 5         URI_PREFIX_MAP.put((byte) 0x01, "http://www.");
 6         URI_PREFIX_MAP.put((byte) 0x02, "https://www.");
 7         URI_PREFIX_MAP.put((byte) 0x03, "http://");
 8         URI_PREFIX_MAP.put((byte) 0x04, "https://");
 9         URI_PREFIX_MAP.put((byte) 0x05, "tel:");
10         URI_PREFIX_MAP.put((byte) 0x06, "mailto:");
11         URI_PREFIX_MAP.put((byte) 0x07, "ftp://anonymous:[email protected]");
12         URI_PREFIX_MAP.put((byte) 0x08, "ftp://ftp.");
13         URI_PREFIX_MAP.put((byte) 0x09, "ftps://");
14         URI_PREFIX_MAP.put((byte) 0x0A, "sftp://");
15         URI_PREFIX_MAP.put((byte) 0x0B, "smb://");
16         URI_PREFIX_MAP.put((byte) 0x0C, "nfs://");
17         URI_PREFIX_MAP.put((byte) 0x0D, "ftp://");
18         URI_PREFIX_MAP.put((byte) 0x0E, "dav://");
19         URI_PREFIX_MAP.put((byte) 0x0F, "news:");
20         URI_PREFIX_MAP.put((byte) 0x10, "telnet://");
21         URI_PREFIX_MAP.put((byte) 0x11, "imap:");
22         URI_PREFIX_MAP.put((byte) 0x12, "rtsp://");
23         URI_PREFIX_MAP.put((byte) 0x13, "urn:");
24         URI_PREFIX_MAP.put((byte) 0x14, "pop:");
25         URI_PREFIX_MAP.put((byte) 0x15, "sip:");
26         URI_PREFIX_MAP.put((byte) 0x16, "sips:");
27         URI_PREFIX_MAP.put((byte) 0x17, "tftp:");
28         URI_PREFIX_MAP.put((byte) 0x18, "btspp://");
29         URI_PREFIX_MAP.put((byte) 0x19, "btl2cap://");
30         URI_PREFIX_MAP.put((byte) 0x1A, "btgoep://");
31         URI_PREFIX_MAP.put((byte) 0x1B, "tcpobex://");
32         URI_PREFIX_MAP.put((byte) 0x1C, "irdaobex://");
33         URI_PREFIX_MAP.put((byte) 0x1D, "file://");
34         URI_PREFIX_MAP.put((byte) 0x1E, "urn:epc:id:");
35         URI_PREFIX_MAP.put((byte) 0x1F, "urn:epc:tag:");
36         URI_PREFIX_MAP.put((byte) 0x20, "urn:epc:pat:");
37         URI_PREFIX_MAP.put((byte) 0x21, "urn:epc:raw:");
38         URI_PREFIX_MAP.put((byte) 0x22, "urn:epc:");
39         URI_PREFIX_MAP.put((byte) 0x23, "urn:nfc:");
40     }
41     private final Uri mUri;
42 
43     private UriRecord(Uri uri) {
44         this.mUri = uri;
45     }
46 
47     public Uri getUri() {
48         return mUri;
49     }
50 
51     // 处理绝对URl(在上面没有定义的头)
52     private static UriRecord parseAbsolute(NdefRecord ndefRecord) {
53         byte[] payload = ndefRecord.getPayload();
54         Uri uri = Uri.parse(new String(payload, Charset.forName("UTF-8")));
55         return new UriRecord(uri);
56 
57     }
58 
59     // 处理已知类型的URI
60     private static UriRecord parseWellKnown(NdefRecord ndefRecord) {
61         if (!Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_URI))
62             return null;
63         // 获得所有字节数据
64         byte[] payload = ndefRecord.getPayload();
65         // 获得前缀
66         String prefix = URI_PREFIX_MAP.get(payload[0]);
67         // 获得前缀所占字节数
68         byte[] prefixBytes = prefix.getBytes(Charset.forName("UTF-8"));
69         // 容纳整个URI的字节数组
70         byte[] fullUri = new byte[prefixBytes.length + payload.length - 1];
71         // copy前缀
72         System.arraycopy(prefixBytes, 0, fullUri, 0, prefixBytes.length);
73         // copy除前缀,后面部分
74         System.arraycopy(payload, 1, fullUri, prefixBytes.length,
75                 payload.length - 1);
76         // 生成uri
77         Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));
78         return new UriRecord(uri);
79 
80     }
81 
82     public static UriRecord parse(NdefRecord record) {
83         short tnf = record.getTnf();
84         if (tnf == NdefRecord.TNF_WELL_KNOWN) {
85             return parseWellKnown(record);
86         } else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
87             return parseAbsolute(record);
88         }
89         throw new IllegalArgumentException("Unknown TNF " + tnf);
90     }
91 }
 1 //选择一个URI,当nfc靠近手机写入NFC,,再靠近手机时读取标签信息并显示
 2 public class ReadWriteUriMainActivity extends Activity {
 3     private TextView mSelectUri;
 4     private String mUri;
 5 
 6     @Override
 7     public void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_read_write_uri_main);
10         mSelectUri = (TextView) findViewById(R.id.textview_uri);
11 
12     }
13 
14     public void onClick_SelectUri(View view) {
15         Intent intent = new Intent(this, UriListActivity.class);
16         startActivityForResult(intent, 1);
17 
18     }
19 
20     @Override
21     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
22         if (requestCode == 1 && resultCode == 1) {
23             mUri = data.getStringExtra("uri");
24             mSelectUri.setText(mUri);
25         }
26     }
27 
28     public void onNewIntent(Intent intent) {
29         if (mUri == null) {
30             //
31             Intent myIntent = new Intent(this, ShowNFCTagContentActivity.class);
32             myIntent.putExtras(intent);
33             myIntent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
34             startActivity(myIntent);
35         } else // 写:URI写入nfc
36         {
37             Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
38             NdefMessage ndefMessage = new NdefMessage(
39                     new NdefRecord[] { createUriRecord(mUri) });
40             if (writeTag(ndefMessage, tag)) {
41                 mUri = null;
42                 mSelectUri.setText("");
43             }
44         }
45     }
46 
47     // 转化为NdefRecord格式
48     public NdefRecord createUriRecord(String uriStr) {
49         byte prefix = 0;
50         for (Byte b : UriRecord.URI_PREFIX_MAP.keySet()) {
51             String prefixStr = UriRecord.URI_PREFIX_MAP.get(b).toLowerCase();
52             if ("".equals(prefixStr))
53                 continue;
54             if (uriStr.toLowerCase().startsWith(prefixStr)) {
55                 prefix = b;
56                 uriStr = uriStr.substring(prefixStr.length());
57                 break;
58             }
59 
60         }
61         // 整个uri;
62         byte[] data = new byte[1 + uriStr.length()];
63         data[0] = prefix;
64         System.arraycopy(uriStr.getBytes(), 0, data, 1, uriStr.length());
65 
66         NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
67                 NdefRecord.RTD_URI, new byte[0], data);
68         return record;
69     }
70 
71     // 写入NFC标签
72     boolean writeTag(NdefMessage message, Tag tag) {
73         int size = message.toByteArray().length;
74         try {
75             Ndef ndef = Ndef.get(tag);
76             if (ndef != null) {
77                 ndef.connect();
78                 if (!ndef.isWritable()) {
79                     return false;
80                 }
81                 if (ndef.getMaxSize() < size) {
82                     return false;
83                 }
84                 ndef.writeNdefMessage(message);
85                 Toast.makeText(this, "ok", Toast.LENGTH_LONG).show();
86                 return true;
87             }
88         } catch (Exception e) {
89             // TODO: handle exception
90         }
91         return false;
92     }
93 }
 1 //显示从NFC标签读取的数据
 2 public class ShowNFCTagContentActivity extends Activity
 3 {
 4     private TextView mTagContent;
 5     private Tag mDetectedTag;
 6     private String mTagText;
 7 
 8     @Override
 9     public void onCreate(Bundle savedInstanceState)
10     {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_show_nfctag_content);
13         mTagContent = (TextView) findViewById(R.id.textview_tag_content);
14         //接收传过来的数据
15         mDetectedTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
16         Ndef ndef = Ndef.get(mDetectedTag);
17         mTagText = ndef.getType() + "\n max size:" + ndef.getMaxSize() + " bytes\n\n";
18         
19         readNFCTag();
20         
21         mTagContent.setText(mTagText);
22     }
23     //读取nfc标签
24     private void readNFCTag()
25     {
26         if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction()))
27         {
28             Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
29             
30             NdefMessage ndefMessage = null;
31             
32             int contentSize = 0;
33             if(rawMsgs != null)
34             {
35                 if(rawMsgs.length > 0)
36                 {
37                     ndefMessage = (NdefMessage)rawMsgs[0];
38                     contentSize = ndefMessage.toByteArray().length;
39                 }
40                 else
41                 {
42                     return;
43                 }
44             }
45             try
46             {
47                 NdefRecord ndefRecord = ndefMessage.getRecords()[0];
48                 UriRecord uriRecord = UriRecord.parse(ndefRecord);
49                 mTagText += uriRecord.getUri().toString() + "\n\nUri\n" + contentSize + " bytes";
50             }
51             catch (Exception e) {
52                 // TODO: handle exception
53             }
54         }
55     }
56 
57 }
 1 //显示URI列表
 2 public class UriListActivity extends ListActivity implements
 3         OnItemClickListener
 4 {
 5     private String uris[] = new String[]
 6     { "http://www.google.com", "http://www.apple.com",
 7             "http://developer.apple.com", "http://www.126.com",
 8             "ftp://192.168.17.160", "https://192.168.17.120",
 9             "smb://192.168.17.100" };
10 
11     @Override
12     public void onCreate(Bundle savedInstanceState)
13     {
14         super.onCreate(savedInstanceState);
15         ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
16                 android.R.layout.simple_list_item_1, android.R.id.text1, uris);
17         setListAdapter(arrayAdapter);
18         getListView().setOnItemClickListener(this);
19     }
20 
21     @Override
22     public void onItemClick(AdapterView<?> parent, View view, int position,
23             long id)
24     {
25         Intent intent = new Intent();
26         intent.putExtra("uri", uris[position]);
27         setResult(1, intent);
28         finish();
29 
30 
31     }
32 
33 }

 

以上是关于NFC技术:读写NFC标签中的Uri数据的主要内容,如果未能解决你的问题,请参考以下文章

NFC读写器的简介

android NFC 请问怎么读写NfcA标签

NFC技术:读写非NDEF格式的数据

NFC读写器是啥

Android NFC 标签读写Demo与历史漏洞概述

在片段中接收 NFC 的应用程序创建托管活动的新实例