NdefRecord.java revision 8bede1704717f594a0f924a57ff46f6300347e30
1013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. Spencer/*
2f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer * Copyright (C) 2010 The Android Open Source Project
3f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer *
4f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer * Licensed under the Apache License, Version 2.0 (the "License");
5f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer * you may not use this file except in compliance with the License.
6f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer * You may obtain a copy of the License at
7f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer *
8f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer *      http://www.apache.org/licenses/LICENSE-2.0
9f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer *
103cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer * Unless required by applicable law or agreed to in writing, software
111f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer * distributed under the License is distributed on an "AS IS" BASIS,
12753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13861ef4b1cffcf30ecd5b6a2216b88345f892f0b7Michael J. Spencer * See the License for the specific language governing permissions and
14f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer * limitations under the License.
15f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer */
16dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
173cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencerpackage android.nfc;
18dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
19f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencerimport android.os.Parcel;
20f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencerimport android.os.Parcelable;
21013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. Spencer
22dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerimport java.lang.UnsupportedOperationException;
23dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
24dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer/**
25dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * Represents a logical (unchunked) NDEF (NFC Data Exchange Format) record.
26dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <p>An NDEF record always contains:
27dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <ul>
28dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <li>3-bit TNF (Type Name Format) field: Indicates how to interpret the type field
29dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <li>Variable length type: Describes the record format
30dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <li>Variable length ID: A unique identifier for the record
31dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <li>Variable length payload: The actual data payload
32dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * </ul>
33dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <p>The underlying record
34dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * representation may be chunked across several NDEF records when the payload is
35dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * large.
36dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer * <p>This is an immutable data class.
37dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer */
38dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerpublic final class NdefRecord implements Parcelable {
39dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
40dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Indicates no type, id, or payload is associated with this NDEF Record.
41dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * <p>
42dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Type, id and payload fields must all be empty to be a valid TNF_EMPTY
43dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * record.
44dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     */
45dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final short TNF_EMPTY = 0x00;
46dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
47dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
48dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Indicates the type field uses the RTD type name format.
49dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * <p>
50dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Use this TNF with RTD types such as RTD_TEXT, RTD_URI.
51dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     */
52dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final short TNF_WELL_KNOWN = 0x01;
53dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
54dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
55dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Indicates the type field contains a value that follows the media-type BNF
56dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * construct defined by RFC 2046.
57dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     */
58dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final short TNF_MIME_MEDIA = 0x02;
59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Indicates the type field contains a value that follows the absolute-URI
62dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * BNF construct defined by RFC 3986.
63dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     */
64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final short TNF_ABSOLUTE_URI = 0x03;
65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
66dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Indicates the type field contains a value that follows the RTD external
68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * name specification.
69dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * <p>
70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Note this TNF should not be used with RTD_TEXT or RTD_URI constants.
71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer     * Those are well known RTD constants, not external RTD constants.
72371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer     */
73dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final short TNF_EXTERNAL_TYPE = 0x04;
74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
75506e579aa034ae84319a36854c8401e23b82f83eMichael J. Spencer    /**
76a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * Indicates the payload type is unknown.
77a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * <p>
78a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * This is similar to the "application/octet-stream" MIME type. The payload
79a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * type is not explicitly encoded within the NDEF Message.
80a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * <p>
81a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     * The type field must be empty to be a valid TNF_UNKNOWN record.
82a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer     */
83a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    public static final short TNF_UNKNOWN = 0x05;
84506e579aa034ae84319a36854c8401e23b82f83eMichael J. Spencer
85a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    /**
865029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * Indicates the payload is an intermediate or final chunk of a chunked
875029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * NDEF Record.
885029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * <p>
895029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * The payload type is specified in the first chunk, and subsequent chunks
905029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * must use TNF_UNCHANGED with an empty type field. TNF_UNCHANGED must not
915029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * be used in any other situation.
925029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     */
935029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    public static final short TNF_UNCHANGED = 0x06;
945029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer
955029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    /**
965029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * Reserved TNF type.
975029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * <p>
985029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this
995029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * value like TNF_UNKNOWN.
1005029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     * @hide
1015029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer     */
1021d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer    public static final short TNF_RESERVED = 0x07;
103dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
104371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    /**
105ee271d8758c8493f2cadf5b9c0ec57431565891bMichael J. Spencer     * RTD Text type. For use with TNF_WELL_KNOWN.
106371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer     */
107936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    public static final byte[] RTD_TEXT = {0x54};  // "T"
1081d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
109371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    /**
110936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer     * RTD URI type. For use with TNF_WELL_KNOWN.
1111d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer     */
1125029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    public static final byte[] RTD_URI = {0x55};   // "U"
1135029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer
1141d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer    /**
1151d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer     * RTD Smart Poster type. For use with TNF_WELL_KNOWN.
116936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer     */
117dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    public static final byte[] RTD_SMART_POSTER = {0x53, 0x70};  // "Sp"
118dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
119dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    /**
1203cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer     * RTD Alternative Carrier type. For use with TNF_WELL_KNOWN.
1219ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     */
1223cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer    public static final byte[] RTD_ALTERNATIVE_CARRIER = {0x61, 0x63};  // "ac"
1233cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
124371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    /**
1253cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer     * RTD Handover Carrier type. For use with TNF_WELL_KNOWN.
1269ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     */
1273cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer    public static final byte[] RTD_HANDOVER_CARRIER = {0x48, 0x63};  // "Hc"
1283cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
1293cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer    /**
1303cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer     * RTD Handover Request type. For use with TNF_WELL_KNOWN.
1319ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     */
1329ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    public static final byte[] RTD_HANDOVER_REQUEST = {0x48, 0x72};  // "Hr"
1339ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
1349ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    /**
1359ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * RTD Handover Select type. For use with TNF_WELL_KNOWN.
1369ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     */
1379ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
1389ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
1399ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private static final byte FLAG_MB = (byte) 0x80;
1409ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private static final byte FLAG_ME = (byte) 0x40;
1419ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private static final byte FLAG_CF = (byte) 0x20;
1429ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private static final byte FLAG_SR = (byte) 0x10;
1439ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private static final byte FLAG_IL = (byte) 0x08;
1449ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
1459ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private final byte mFlags;
1469ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private final short mTnf;
1479ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private final byte[] mType;
1489ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private final byte[] mId;
1499ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    private final byte[] mPayload;
1509ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
1519ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    /**
1529ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * Construct an NDEF Record.
1539ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * <p>
1549ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * Applications should not attempt to manually chunk NDEF Records - the
1559ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * implementation of android.nfc will automatically chunk an NDEF Record
1569ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * when necessary (and only present a single logical NDEF Record to the
1579ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     * application). So applications should not use TNF_UNCHANGED.
1589ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     *
1593cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer     * @param tnf  a 3-bit TNF constant
160106aa731bf86c632a6362497742c6df7bce61a07Michael J. Spencer     * @param type byte array, containing zero to 255 bytes, must not be null
161106aa731bf86c632a6362497742c6df7bce61a07Michael J. Spencer     * @param id   byte array, containing zero to 255 bytes, must not be null
1623cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer     * @param payload byte array, containing zero to (2 ** 32 - 1) bytes,
1639ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     *                must not be null
1649ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer     */
1659ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer    public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
1669ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer        /* New NDEF records created by applications will have FLAG_MB|FLAG_ME
1679ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer         * set by default; when multiple records are stored in a
1683cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer         * {@link NdefMessage}, these flags will be corrected when the {@link NdefMessage}
1696d6d16a5fc054fb3f7032297d0a15abb659be7efBenjamin Kramer         * is serialized to bytes.
170753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer         */
171753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer        this(tnf, type, id, payload, (byte)(FLAG_MB|FLAG_ME));
172753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer    }
173753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer
174753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer    /**
175753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer     * @hide
176753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer     */
177753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer    /*package*/ NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload, byte flags) {
178753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer        /* check arguments */
179753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer        if ((type == null) || (id == null) || (payload == null)) {
180753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer            throw new IllegalArgumentException("Illegal null argument");
181753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer        }
182f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
183f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer        if (tnf < 0 || tnf > 0x07) {
184f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer            throw new IllegalArgumentException("TNF out of range " + tnf);
185        }
186
187        /* Determine if it is a short record */
188        if(payload.length < 0xFF) {
189            flags |= FLAG_SR;
190        }
191
192        /* Determine if an id is present */
193        if(id.length != 0) {
194            flags |= FLAG_IL;
195        }
196
197        mFlags = flags;
198        mTnf = tnf;
199        mType = type.clone();
200        mId = id.clone();
201        mPayload = payload.clone();
202    }
203
204    /**
205     * Construct an NDEF Record from raw bytes.
206     * <p>
207     * Validation is performed to make sure the header is valid, and that
208     * the id, type and payload sizes appear to be valid.
209     *
210     * @throws FormatException if the data is not a valid NDEF record
211     */
212    public NdefRecord(byte[] data) throws FormatException {
213        /* Prevent compiler to complain about unassigned final fields */
214        mFlags = 0;
215        mTnf = 0;
216        mType = null;
217        mId = null;
218        mPayload = null;
219        /* Perform actual parsing */
220        if (parseNdefRecord(data) == -1) {
221            throw new FormatException("Error while parsing NDEF record");
222        }
223    }
224
225    /**
226     * Returns the 3-bit TNF.
227     * <p>
228     * TNF is the top-level type.
229     */
230    public short getTnf() {
231        return mTnf;
232    }
233
234    /**
235     * Returns the variable length Type field.
236     * <p>
237     * This should be used in conjunction with the TNF field to determine the
238     * payload format.
239     */
240    public byte[] getType() {
241        return mType.clone();
242    }
243
244    /**
245     * Returns the variable length ID.
246     */
247    public byte[] getId() {
248        return mId.clone();
249    }
250
251    /**
252     * Returns the variable length payload.
253     */
254    public byte[] getPayload() {
255        return mPayload.clone();
256    }
257
258    /**
259     * Returns this entire NDEF Record as a byte array.
260     */
261    public byte[] toByteArray() {
262        return generate(mFlags, mTnf, mType, mId, mPayload);
263    }
264
265    public int describeContents() {
266        return 0;
267    }
268
269    public void writeToParcel(Parcel dest, int flags) {
270        dest.writeInt(mFlags);
271        dest.writeInt(mTnf);
272        dest.writeInt(mType.length);
273        dest.writeByteArray(mType);
274        dest.writeInt(mId.length);
275        dest.writeByteArray(mId);
276        dest.writeInt(mPayload.length);
277        dest.writeByteArray(mPayload);
278    }
279
280    public static final Parcelable.Creator<NdefRecord> CREATOR =
281            new Parcelable.Creator<NdefRecord>() {
282        public NdefRecord createFromParcel(Parcel in) {
283            byte flags = (byte)in.readInt();
284            short tnf = (short)in.readInt();
285            int typeLength = in.readInt();
286            byte[] type = new byte[typeLength];
287            in.readByteArray(type);
288            int idLength = in.readInt();
289            byte[] id = new byte[idLength];
290            in.readByteArray(id);
291            int payloadLength = in.readInt();
292            byte[] payload = new byte[payloadLength];
293            in.readByteArray(payload);
294
295            return new NdefRecord(tnf, type, id, payload, flags);
296        }
297        public NdefRecord[] newArray(int size) {
298            return new NdefRecord[size];
299        }
300    };
301
302    private native int parseNdefRecord(byte[] data);
303    private native byte[] generate(short flags, short tnf, byte[] type, byte[] id, byte[] data);
304}
305