• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.example.android.nfc.record;
17 
18 import android.app.Activity;
19 import android.net.Uri;
20 import android.nfc.NdefRecord;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.TextView;
25 
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.BiMap;
28 import com.google.common.collect.ImmutableBiMap;
29 import com.google.common.primitives.Bytes;
30 
31 import com.example.android.nfc.R;
32 
33 import java.nio.charset.Charset;
34 import java.util.Arrays;
35 
36 /**
37  * A parsed record containing a Uri.
38  */
39 public class UriRecord implements ParsedNdefRecord {
40 
41     private static final String TAG = "UriRecord";
42 
43     public static final String RECORD_TYPE = "UriRecord";
44 
45     /**
46      * NFC Forum "URI Record Type Definition"
47      *
48      * This is a mapping of "URI Identifier Codes" to URI string prefixes,
49      * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
50      */
51     private static final BiMap<Byte, String> URI_PREFIX_MAP = ImmutableBiMap.<Byte, String>builder()
52             .put((byte) 0x00, "")
53             .put((byte) 0x01, "http://www.")
54             .put((byte) 0x02, "https://www.")
55             .put((byte) 0x03, "http://")
56             .put((byte) 0x04, "https://")
57             .put((byte) 0x05, "tel:")
58             .put((byte) 0x06, "mailto:")
59             .put((byte) 0x07, "ftp://anonymous:anonymous@")
60             .put((byte) 0x08, "ftp://ftp.")
61             .put((byte) 0x09, "ftps://")
62             .put((byte) 0x0A, "sftp://")
63             .put((byte) 0x0B, "smb://")
64             .put((byte) 0x0C, "nfs://")
65             .put((byte) 0x0D, "ftp://")
66             .put((byte) 0x0E, "dav://")
67             .put((byte) 0x0F, "news:")
68             .put((byte) 0x10, "telnet://")
69             .put((byte) 0x11, "imap:")
70             .put((byte) 0x12, "rtsp://")
71             .put((byte) 0x13, "urn:")
72             .put((byte) 0x14, "pop:")
73             .put((byte) 0x15, "sip:")
74             .put((byte) 0x16, "sips:")
75             .put((byte) 0x17, "tftp:")
76             .put((byte) 0x18, "btspp://")
77             .put((byte) 0x19, "btl2cap://")
78             .put((byte) 0x1A, "btgoep://")
79             .put((byte) 0x1B, "tcpobex://")
80             .put((byte) 0x1C, "irdaobex://")
81             .put((byte) 0x1D, "file://")
82             .put((byte) 0x1E, "urn:epc:id:")
83             .put((byte) 0x1F, "urn:epc:tag:")
84             .put((byte) 0x20, "urn:epc:pat:")
85             .put((byte) 0x21, "urn:epc:raw:")
86             .put((byte) 0x22, "urn:epc:")
87             .put((byte) 0x23, "urn:nfc:")
88             .build();
89 
90     private final Uri mUri;
91 
UriRecord(Uri uri)92     private UriRecord(Uri uri) {
93         this.mUri = Preconditions.checkNotNull(uri);
94     }
95 
getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset)96     public View getView(Activity activity, LayoutInflater inflater, ViewGroup parent, int offset) {
97         TextView text = (TextView) inflater.inflate(R.layout.tag_text, parent, false);
98         text.setText(mUri.toString());
99         return text;
100     }
101 
getUri()102     public Uri getUri() {
103         return mUri;
104     }
105 
106     /**
107      * Convert {@link android.nfc.NdefRecord} into a {@link android.net.Uri}.
108      * This will handle both TNF_WELL_KNOWN / RTD_URI and TNF_ABSOLUTE_URI.
109      *
110      * @throws IllegalArgumentException if the NdefRecord is not a record
111      *         containing a URI.
112      */
parse(NdefRecord record)113     public static UriRecord parse(NdefRecord record) {
114         short tnf = record.getTnf();
115         if (tnf == NdefRecord.TNF_WELL_KNOWN) {
116             return parseWellKnown(record);
117         } else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) {
118             return parseAbsolute(record);
119         }
120         throw new IllegalArgumentException("Unknown TNF " + tnf);
121     }
122 
123     /** Parse and absolute URI record */
parseAbsolute(NdefRecord record)124     private static UriRecord parseAbsolute(NdefRecord record) {
125         byte[] payload = record.getPayload();
126         Uri uri = Uri.parse(new String(payload, Charset.forName("UTF-8")));
127         return new UriRecord(uri);
128     }
129 
130     /** Parse an well known URI record */
parseWellKnown(NdefRecord record)131     private static UriRecord parseWellKnown(NdefRecord record) {
132         Preconditions.checkArgument(Arrays.equals(record.getType(), NdefRecord.RTD_URI));
133         byte[] payload = record.getPayload();
134         /*
135          * payload[0] contains the URI Identifier Code, per the
136          * NFC Forum "URI Record Type Definition" section 3.2.2.
137          *
138          * payload[1]...payload[payload.length - 1] contains the rest of
139          * the URI.
140          */
141         String prefix = URI_PREFIX_MAP.get(payload[0]);
142         byte[] fullUri =
143             Bytes.concat(prefix.getBytes(Charset.forName("UTF-8")), Arrays.copyOfRange(payload, 1,
144                 payload.length));
145         Uri uri = Uri.parse(new String(fullUri, Charset.forName("UTF-8")));
146         return new UriRecord(uri);
147     }
148 
isUri(NdefRecord record)149     public static boolean isUri(NdefRecord record) {
150         try {
151             parse(record);
152             return true;
153         } catch (IllegalArgumentException e) {
154             return false;
155         }
156     }
157 
158     private static final byte[] EMPTY = new byte[0];
159 }
160