NdefMessage.java revision a356bf1cd81614a94ef6c720998792480ade4c84
1dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly/* 2dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * Copyright (C) 2010 The Android Open Source Project 3dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * 4dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * you may not use this file except in compliance with the License. 6dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * You may obtain a copy of the License at 7dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * 8dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * 10dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * Unless required by applicable law or agreed to in writing, software 11dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * See the License for the specific language governing permissions and 14dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * limitations under the License. 15dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 16dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 17dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pellypackage android.nfc; 18dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 19a356bf1cd81614a94ef6c720998792480ade4c84Nick Pellyimport java.nio.ByteBuffer; 20a356bf1cd81614a94ef6c720998792480ade4c84Nick Pellyimport java.util.Arrays; 21a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 22dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pellyimport android.os.Parcel; 23dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pellyimport android.os.Parcelable; 24dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 25a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 26dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly/** 27a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Represents an immutable NDEF Message. 28a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p> 29a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * NDEF (NFC Data Exchange Format) is a light-weight binary format, 30a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * used to encapsulate typed data. It is specified by the NFC Forum, 31a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * for transmission and storage with NFC, however it is transport agnostic. 32a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p> 33a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * NDEF defines messages and records. An NDEF Record contains 34a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * typed data, such as MIME-type media, a URI, or a custom 35a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * application payload. An NDEF Message is a container for 36a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * one or more NDEF Records. 37a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p> 38a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * When an Android device receives an NDEF Message 39a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * (for example by reading an NFC tag) it processes it through 40a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * a dispatch mechanism to determine an activity to launch. 41a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * The type of the <em>first</em> record in the message has 42a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * special importance for message dispatch, so design this record 43a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * carefully. 44a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p> 45a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from 46a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * binary data, or {@link #NdefMessage(NdefRecord[])} to 47a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * construct from one or more {@link NdefRecord}s. 48a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p class="note"> 49a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * {@link NdefMessage} and {@link NdefRecord} implementations are 50a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * always available, even on Android devices that do not have NFC hardware. 51a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p class="note"> 52a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * {@link NdefRecord}s are intended to be immutable (and thread-safe), 53a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * however they may contain mutable fields. So take care not to modify 54a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * mutable fields passed into constructors, or modify mutable fields 55a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * obtained by getter methods, unless such modification is explicitly 56a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * marked as safe. 57a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 58a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @see NfcAdapter#ACTION_NDEF_DISCOVERED 59a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @see NdefRecord 60dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 6111b075e218b9921a953eeebe73fcd1a8a81f764bNick Pellypublic final class NdefMessage implements Parcelable { 62590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly private final NdefRecord[] mRecords; 63590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 64dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly /** 65a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Construct an NDEF Message by parsing raw bytes.<p> 66a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Strict validation of the NDEF binary structure is performed: 67a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * there must be at least one record, every record flag must 68a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * be correct, and the total length of the message must match 69a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * the length of the input data.<p> 70a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * This parser can handle chunked records, and converts them 71a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * into logical {@link NdefRecord}s within the message.<p> 72a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Once the input data has been parsed to one or more logical 73a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * records, basic validation of the tnf, type, id, and payload fields 74a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * of each record is performed, as per the documentation on 75a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p> 76a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * If either strict validation of the binary format fails, or 77a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * basic validation during record construction fails, a 78a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * {@link FormatException} is thrown<p> 79a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Deep inspection of the type, id and payload fields of 80a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * each record is not performed, so it is possible to parse input 81a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * that has a valid binary format and confirms to the basic 82a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * validation requirements of 83a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}, 84a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * but fails more strict requirements as specified by the 85a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * NFC Forum. 86a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 87a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * <p class="note"> 88a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * It is safe to re-use the data byte array after construction: 89a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * this constructor will make an internal copy of all necessary fields. 90a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 91a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @param data raw bytes to parse 92a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @throws FormatException if the data cannot be parsed 93dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 94590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public NdefMessage(byte[] data) throws FormatException { 95a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (data == null) { 96a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new NullPointerException("null data"); 97a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 98a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly ByteBuffer buffer = ByteBuffer.wrap(data); 99a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 100a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly mRecords = NdefRecord.parse(buffer, false); 101a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 102a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (buffer.remaining() > 0) { 103a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new FormatException("trailing data"); 104590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 105dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 106dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 107dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly /** 108a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Construct an NDEF Message from one or more NDEF Records. 109a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 110a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @param record first record (mandatory) 111a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @param records additional records (optional) 112a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly */ 113a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly public NdefMessage(NdefRecord record, NdefRecord ... records) { 114a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly // validate 115a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (record == null) { 116a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new NullPointerException("record cannot be null"); 117a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 118a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly for (NdefRecord r : records) { 119a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (r == null) { 120a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new NullPointerException("record cannot be null"); 121a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 122a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 123a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 124a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly mRecords = new NdefRecord[1 + records.length]; 125a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly mRecords[0] = record; 126a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly System.arraycopy(records, 0, mRecords, 1, records.length); 127a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 128a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 129a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly /** 130a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Construct an NDEF Message from one or more NDEF Records. 131a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 132a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @param records one or more records 133dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 134dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public NdefMessage(NdefRecord[] records) { 135a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly // validate 136a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (records.length < 1) { 137a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new IllegalArgumentException("must have at least one record"); 138a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 139a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly for (NdefRecord r : records) { 140a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (r == null) { 141a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly throw new NullPointerException("records cannot contain null"); 142a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 143a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 144a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 145a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly mRecords = records; 146dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 147dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 148dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly /** 149a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Get the NDEF Records inside this NDEF Message.<p> 150a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * An NDEF Message always has one or more NDEF Records. 151dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly * 152a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @return array of one or more NDEF records. 153dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 154dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public NdefRecord[] getRecords() { 155a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly return mRecords; 156dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 157dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 158dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly /** 159a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Return this NDEF MEssage as raw bytes.<p> 160a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * The NDEF Message is formatted as per the NDEF 1.0 specification, 161a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * and the byte array is suitable for network transmission or storage 162a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * in an NFC Forum NDEF compatible tag.<p> 163a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * This method will not chunk any records, and will always use the 164a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * short record (SR) format and omit the identifier field when possible. 165a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * 166a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * @return NDEF Message in binary format 167dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly */ 168dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public byte[] toByteArray() { 169a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly int length = 0; 170a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly for (NdefRecord r : mRecords) { 171a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly length += r.getByteLength(); 172a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 173590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 174a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly ByteBuffer buffer = ByteBuffer.allocate(length); 175590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 176a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly for (int i=0; i<mRecords.length; i++) { 177a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly boolean mb = (i == 0); // first record 178a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly boolean me = (i == mRecords.length - 1); // last record 179a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly mRecords[i].writeToByteBuffer(buffer, mb, me); 180590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 181590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 182a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly return buffer.array(); 183dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 184dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 1853ebd59bb5dc9f421fd2b9b789ea824746d58fff7Jason parks @Override 186dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public int describeContents() { 187dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly return 0; 188dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 189dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 1903ebd59bb5dc9f421fd2b9b789ea824746d58fff7Jason parks @Override 191dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public void writeToParcel(Parcel dest, int flags) { 192590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly dest.writeInt(mRecords.length); 193590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly dest.writeTypedArray(mRecords, flags); 194dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 195dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly 196dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public static final Parcelable.Creator<NdefMessage> CREATOR = 197dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly new Parcelable.Creator<NdefMessage>() { 1983ebd59bb5dc9f421fd2b9b789ea824746d58fff7Jason parks @Override 199dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public NdefMessage createFromParcel(Parcel in) { 200590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly int recordsLength = in.readInt(); 201590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly NdefRecord[] records = new NdefRecord[recordsLength]; 202590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly in.readTypedArray(records, NdefRecord.CREATOR); 203590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return new NdefMessage(records); 204dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 2053ebd59bb5dc9f421fd2b9b789ea824746d58fff7Jason parks @Override 206dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly public NdefMessage[] newArray(int size) { 207590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return new NdefMessage[size]; 208dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly } 209dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly }; 210590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 211a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly @Override 212a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly public int hashCode() { 213a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly return Arrays.hashCode(mRecords); 214a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 215a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 216a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly /** 217a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * Returns true if the specified NDEF Message contains 218a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly * identical NDEF Records. 219a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly */ 220a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly @Override 221a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly public boolean equals(Object obj) { 222a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (this == obj) return true; 223a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (obj == null) return false; 224a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly if (getClass() != obj.getClass()) return false; 225a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly NdefMessage other = (NdefMessage) obj; 226a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly return Arrays.equals(mRecords, other.mRecords); 227a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 228a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly 229a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly @Override 230a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly public String toString() { 231a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly return "NdefMessage " + Arrays.toString(mRecords); 232a356bf1cd81614a94ef6c720998792480ade4c84Nick Pelly } 233dc993791fc3cf7a270921f7419b0c6b875bbd92bNick Pelly}