NdefMessage.java revision c9f7890a203a013646650a695157277df81b6a17
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 17package android.nfc; 18 19import android.nfc.NdefRecord; 20import android.os.Parcel; 21import android.os.Parcelable; 22 23/** 24 * Represents an NDEF (NFC Data Exchange Format) data message that contains one or more {@link 25 * NdefRecord}s. 26 * <p>An NDEF message includes "records" that can contain different sets of data, such as 27 * MIME-type media, a URI, or one of the supported RTD types (see {@link NdefRecord}). An NDEF 28 * message always contains zero or more NDEF records.</p> 29 * <p>This is an immutable data class. 30 */ 31public class NdefMessage implements Parcelable { 32 private static final byte FLAG_MB = (byte) 0x80; 33 private static final byte FLAG_ME = (byte) 0x40; 34 35 private final NdefRecord[] mRecords; 36 37 //TODO(npelly) FormatException 38 /** 39 * Create an NDEF message from raw bytes. 40 * <p> 41 * Validation is performed to make sure the Record format headers are valid, 42 * and the ID + TYPE + PAYLOAD fields are of the correct size. 43 * @throws FormatException 44 * 45 * @hide 46 */ 47 public NdefMessage(byte[] data) throws FormatException { 48 mRecords = null; // stop compiler complaints about final field 49 if (parseNdefMessage(data) == -1) { 50 throw new FormatException("Error while parsing NDEF message"); 51 } 52 } 53 54 /** 55 * Create an NDEF message from NDEF records. 56 */ 57 public NdefMessage(NdefRecord[] records) { 58 mRecords = new NdefRecord[records.length]; 59 System.arraycopy(records, 0, mRecords, 0, records.length); 60 } 61 62 /** 63 * Get the NDEF records inside this NDEF message. 64 * 65 * @return array of zero or more NDEF records. 66 */ 67 public NdefRecord[] getRecords() { 68 return mRecords.clone(); 69 } 70 71 /** 72 * Get a byte array representation of this NDEF message. 73 * 74 * @return byte array 75 * @hide 76 */ 77 public byte[] toByteArray() { 78 //TODO(nxp): do not return null 79 //TODO(nxp): allocate the byte array once, copy each record once 80 //TODO(nxp): process MB and ME flags outside loop 81 if ((mRecords == null) || (mRecords.length == 0)) 82 return null; 83 84 byte[] msg = {}; 85 86 for (int i = 0; i < mRecords.length; i++) { 87 byte[] record = mRecords[i].toByteArray(); 88 byte[] tmp = new byte[msg.length + record.length]; 89 90 /* Make sure the Message Begin flag is set only for the first record */ 91 if (i == 0) { 92 record[0] |= FLAG_MB; 93 } else { 94 record[0] &= ~FLAG_MB; 95 } 96 97 /* Make sure the Message End flag is set only for the last record */ 98 if (i == (mRecords.length - 1)) { 99 record[0] |= FLAG_ME; 100 } else { 101 record[0] &= ~FLAG_ME; 102 } 103 104 System.arraycopy(msg, 0, tmp, 0, msg.length); 105 System.arraycopy(record, 0, tmp, msg.length, record.length); 106 107 msg = tmp; 108 } 109 110 return msg; 111 } 112 113 public int describeContents() { 114 return 0; 115 } 116 117 public void writeToParcel(Parcel dest, int flags) { 118 dest.writeInt(mRecords.length); 119 dest.writeTypedArray(mRecords, flags); 120 } 121 122 public static final Parcelable.Creator<NdefMessage> CREATOR = 123 new Parcelable.Creator<NdefMessage>() { 124 public NdefMessage createFromParcel(Parcel in) { 125 int recordsLength = in.readInt(); 126 NdefRecord[] records = new NdefRecord[recordsLength]; 127 in.readTypedArray(records, NdefRecord.CREATOR); 128 return new NdefMessage(records); 129 } 130 public NdefMessage[] newArray(int size) { 131 return new NdefMessage[size]; 132 } 133 }; 134 135 private native int parseNdefMessage(byte[] data); 136}