Loading api/15.txt +0 −1 Original line number Diff line number Diff line Loading @@ -12659,7 +12659,6 @@ package android.nfc { method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]); method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); method public static deprecated android.nfc.NfcAdapter getDefaultAdapter(); method public boolean isEnabled(); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); method public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...); api/current.txt +6 −3 Original line number Diff line number Diff line Loading @@ -12602,10 +12602,12 @@ package android.nfc { public class FormatException extends java.lang.Exception { ctor public FormatException(); ctor public FormatException(java.lang.String); ctor public FormatException(java.lang.String, java.lang.Throwable); } public final class NdefMessage implements android.os.Parcelable { ctor public NdefMessage(byte[]) throws android.nfc.FormatException; ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...); ctor public NdefMessage(android.nfc.NdefRecord[]); method public int describeContents(); method public android.nfc.NdefRecord[] getRecords(); Loading @@ -12616,8 +12618,10 @@ package android.nfc { public final class NdefRecord implements android.os.Parcelable { ctor public NdefRecord(short, byte[], byte[], byte[]); ctor public NdefRecord(byte[]) throws android.nfc.FormatException; ctor public deprecated NdefRecord(byte[]) throws android.nfc.FormatException; method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String); method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]); method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]); method public static android.nfc.NdefRecord createUri(android.net.Uri); method public static android.nfc.NdefRecord createUri(java.lang.String); method public int describeContents(); Loading @@ -12625,7 +12629,7 @@ package android.nfc { method public byte[] getPayload(); method public short getTnf(); method public byte[] getType(); method public byte[] toByteArray(); method public deprecated byte[] toByteArray(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public static final byte[] RTD_ALTERNATIVE_CARRIER; Loading @@ -12650,7 +12654,6 @@ package android.nfc { method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]); method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); method public static deprecated android.nfc.NfcAdapter getDefaultAdapter(); method public boolean isEnabled(); method public boolean isNdefPushEnabled(); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); core/java/android/nfc/FormatException.java +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ public class FormatException extends Exception { public FormatException(String message) { super(message); } public FormatException(String message, Throwable e) { super(message, e); } } core/java/android/nfc/NdefMessage.java +154 −53 Original line number Diff line number Diff line Loading @@ -16,90 +16,170 @@ package android.nfc; import java.nio.ByteBuffer; import java.util.Arrays; import android.os.Parcel; import android.os.Parcelable; /** * Represents an NDEF (NFC Data Exchange Format) data message that contains one or more {@link * NdefRecord}s. * <p>An NDEF message includes "records" that can contain different sets of data, such as * MIME-type media, a URI, or one of the supported RTD types (see {@link NdefRecord}). An NDEF * message always contains zero or more NDEF records.</p> * <p>This is an immutable data class. * Represents an immutable NDEF Message. * <p> * NDEF (NFC Data Exchange Format) is a light-weight binary format, * used to encapsulate typed data. It is specified by the NFC Forum, * for transmission and storage with NFC, however it is transport agnostic. * <p> * NDEF defines messages and records. An NDEF Record contains * typed data, such as MIME-type media, a URI, or a custom * application payload. An NDEF Message is a container for * one or more NDEF Records. * <p> * When an Android device receives an NDEF Message * (for example by reading an NFC tag) it processes it through * a dispatch mechanism to determine an activity to launch. * The type of the <em>first</em> record in the message has * special importance for message dispatch, so design this record * carefully. * <p> * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from * binary data, or {@link #NdefMessage(NdefRecord[])} to * construct from one or more {@link NdefRecord}s. * <p class="note"> * {@link NdefMessage} and {@link NdefRecord} implementations are * always available, even on Android devices that do not have NFC hardware. * <p class="note"> * {@link NdefRecord}s are intended to be immutable (and thread-safe), * however they may contain mutable fields. So take care not to modify * mutable fields passed into constructors, or modify mutable fields * obtained by getter methods, unless such modification is explicitly * marked as safe. * * @see NfcAdapter#ACTION_NDEF_DISCOVERED * @see NdefRecord */ public final class NdefMessage implements Parcelable { private static final byte FLAG_MB = (byte) 0x80; private static final byte FLAG_ME = (byte) 0x40; private final NdefRecord[] mRecords; /** * Create an NDEF message from raw bytes. * <p> * Validation is performed to make sure the Record format headers are valid, * and the ID + TYPE + PAYLOAD fields are of the correct size. * @throws FormatException * Construct an NDEF Message by parsing raw bytes.<p> * Strict validation of the NDEF binary structure is performed: * there must be at least one record, every record flag must * be correct, and the total length of the message must match * the length of the input data.<p> * This parser can handle chunked records, and converts them * into logical {@link NdefRecord}s within the message.<p> * Once the input data has been parsed to one or more logical * records, basic validation of the tnf, type, id, and payload fields * of each record is performed, as per the documentation on * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p> * If either strict validation of the binary format fails, or * basic validation during record construction fails, a * {@link FormatException} is thrown<p> * Deep inspection of the type, id and payload fields of * each record is not performed, so it is possible to parse input * that has a valid binary format and confirms to the basic * validation requirements of * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}, * but fails more strict requirements as specified by the * NFC Forum. * * <p class="note"> * It is safe to re-use the data byte array after construction: * this constructor will make an internal copy of all necessary fields. * * @param data raw bytes to parse * @throws FormatException if the data cannot be parsed */ public NdefMessage(byte[] data) throws FormatException { mRecords = null; // stop compiler complaints about final field if (parseNdefMessage(data) == -1) { throw new FormatException("Error while parsing NDEF message"); if (data == null) { throw new NullPointerException("null data"); } ByteBuffer buffer = ByteBuffer.wrap(data); mRecords = NdefRecord.parse(buffer, false); if (buffer.remaining() > 0) { throw new FormatException("trailing data"); } } /** * Construct an NDEF Message from one or more NDEF Records. * * @param record first record (mandatory) * @param records additional records (optional) */ public NdefMessage(NdefRecord record, NdefRecord ... records) { // validate if (record == null) { throw new NullPointerException("record cannot be null"); } for (NdefRecord r : records) { if (r == null) { throw new NullPointerException("record cannot be null"); } } mRecords = new NdefRecord[1 + records.length]; mRecords[0] = record; System.arraycopy(records, 0, mRecords, 1, records.length); } /** * Create an NDEF message from NDEF records. * Construct an NDEF Message from one or more NDEF Records. * * @param records one or more records */ public NdefMessage(NdefRecord[] records) { mRecords = new NdefRecord[records.length]; System.arraycopy(records, 0, mRecords, 0, records.length); // validate if (records.length < 1) { throw new IllegalArgumentException("must have at least one record"); } for (NdefRecord r : records) { if (r == null) { throw new NullPointerException("records cannot contain null"); } } mRecords = records; } /** * Get the NDEF records inside this NDEF message. * Get the NDEF Records inside this NDEF Message.<p> * An NDEF Message always has one or more NDEF Records. * * @return array of zero or more NDEF records. * @return array of one or more NDEF records. */ public NdefRecord[] getRecords() { return mRecords.clone(); return mRecords; } /** * Returns a byte array representation of this entire NDEF message. * Return this NDEF MEssage as raw bytes.<p> * The NDEF Message is formatted as per the NDEF 1.0 specification, * and the byte array is suitable for network transmission or storage * in an NFC Forum NDEF compatible tag.<p> * This method will not chunk any records, and will always use the * short record (SR) format and omit the identifier field when possible. * * @return NDEF Message in binary format */ public byte[] toByteArray() { //TODO: allocate the byte array once, copy each record once //TODO: process MB and ME flags outside loop if ((mRecords == null) || (mRecords.length == 0)) return new byte[0]; byte[] msg = {}; for (int i = 0; i < mRecords.length; i++) { byte[] record = mRecords[i].toByteArray(); byte[] tmp = new byte[msg.length + record.length]; /* Make sure the Message Begin flag is set only for the first record */ if (i == 0) { record[0] |= FLAG_MB; } else { record[0] &= ~FLAG_MB; } /* Make sure the Message End flag is set only for the last record */ if (i == (mRecords.length - 1)) { record[0] |= FLAG_ME; } else { record[0] &= ~FLAG_ME; int length = 0; for (NdefRecord r : mRecords) { length += r.getByteLength(); } System.arraycopy(msg, 0, tmp, 0, msg.length); System.arraycopy(record, 0, tmp, msg.length, record.length); ByteBuffer buffer = ByteBuffer.allocate(length); msg = tmp; for (int i=0; i<mRecords.length; i++) { boolean mb = (i == 0); // first record boolean me = (i == mRecords.length - 1); // last record mRecords[i].writeToByteBuffer(buffer, mb, me); } return msg; return buffer.array(); } @Override Loading Loading @@ -128,5 +208,26 @@ public final class NdefMessage implements Parcelable { } }; private native int parseNdefMessage(byte[] data); @Override public int hashCode() { return Arrays.hashCode(mRecords); } /** * Returns true if the specified NDEF Message contains * identical NDEF Records. */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; NdefMessage other = (NdefMessage) obj; return Arrays.equals(mRecords, other.mRecords); } @Override public String toString() { return "NdefMessage " + Arrays.toString(mRecords); } } No newline at end of file Loading
api/15.txt +0 −1 Original line number Diff line number Diff line Loading @@ -12659,7 +12659,6 @@ package android.nfc { method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]); method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); method public static deprecated android.nfc.NfcAdapter getDefaultAdapter(); method public boolean isEnabled(); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...); method public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
api/current.txt +6 −3 Original line number Diff line number Diff line Loading @@ -12602,10 +12602,12 @@ package android.nfc { public class FormatException extends java.lang.Exception { ctor public FormatException(); ctor public FormatException(java.lang.String); ctor public FormatException(java.lang.String, java.lang.Throwable); } public final class NdefMessage implements android.os.Parcelable { ctor public NdefMessage(byte[]) throws android.nfc.FormatException; ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...); ctor public NdefMessage(android.nfc.NdefRecord[]); method public int describeContents(); method public android.nfc.NdefRecord[] getRecords(); Loading @@ -12616,8 +12618,10 @@ package android.nfc { public final class NdefRecord implements android.os.Parcelable { ctor public NdefRecord(short, byte[], byte[], byte[]); ctor public NdefRecord(byte[]) throws android.nfc.FormatException; ctor public deprecated NdefRecord(byte[]) throws android.nfc.FormatException; method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String); method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]); method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]); method public static android.nfc.NdefRecord createUri(android.net.Uri); method public static android.nfc.NdefRecord createUri(java.lang.String); method public int describeContents(); Loading @@ -12625,7 +12629,7 @@ package android.nfc { method public byte[] getPayload(); method public short getTnf(); method public byte[] getType(); method public byte[] toByteArray(); method public deprecated byte[] toByteArray(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public static final byte[] RTD_ALTERNATIVE_CARRIER; Loading @@ -12650,7 +12654,6 @@ package android.nfc { method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]); method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage); method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context); method public static deprecated android.nfc.NfcAdapter getDefaultAdapter(); method public boolean isEnabled(); method public boolean isNdefPushEnabled(); method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
core/java/android/nfc/FormatException.java +4 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,8 @@ public class FormatException extends Exception { public FormatException(String message) { super(message); } public FormatException(String message, Throwable e) { super(message, e); } }
core/java/android/nfc/NdefMessage.java +154 −53 Original line number Diff line number Diff line Loading @@ -16,90 +16,170 @@ package android.nfc; import java.nio.ByteBuffer; import java.util.Arrays; import android.os.Parcel; import android.os.Parcelable; /** * Represents an NDEF (NFC Data Exchange Format) data message that contains one or more {@link * NdefRecord}s. * <p>An NDEF message includes "records" that can contain different sets of data, such as * MIME-type media, a URI, or one of the supported RTD types (see {@link NdefRecord}). An NDEF * message always contains zero or more NDEF records.</p> * <p>This is an immutable data class. * Represents an immutable NDEF Message. * <p> * NDEF (NFC Data Exchange Format) is a light-weight binary format, * used to encapsulate typed data. It is specified by the NFC Forum, * for transmission and storage with NFC, however it is transport agnostic. * <p> * NDEF defines messages and records. An NDEF Record contains * typed data, such as MIME-type media, a URI, or a custom * application payload. An NDEF Message is a container for * one or more NDEF Records. * <p> * When an Android device receives an NDEF Message * (for example by reading an NFC tag) it processes it through * a dispatch mechanism to determine an activity to launch. * The type of the <em>first</em> record in the message has * special importance for message dispatch, so design this record * carefully. * <p> * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from * binary data, or {@link #NdefMessage(NdefRecord[])} to * construct from one or more {@link NdefRecord}s. * <p class="note"> * {@link NdefMessage} and {@link NdefRecord} implementations are * always available, even on Android devices that do not have NFC hardware. * <p class="note"> * {@link NdefRecord}s are intended to be immutable (and thread-safe), * however they may contain mutable fields. So take care not to modify * mutable fields passed into constructors, or modify mutable fields * obtained by getter methods, unless such modification is explicitly * marked as safe. * * @see NfcAdapter#ACTION_NDEF_DISCOVERED * @see NdefRecord */ public final class NdefMessage implements Parcelable { private static final byte FLAG_MB = (byte) 0x80; private static final byte FLAG_ME = (byte) 0x40; private final NdefRecord[] mRecords; /** * Create an NDEF message from raw bytes. * <p> * Validation is performed to make sure the Record format headers are valid, * and the ID + TYPE + PAYLOAD fields are of the correct size. * @throws FormatException * Construct an NDEF Message by parsing raw bytes.<p> * Strict validation of the NDEF binary structure is performed: * there must be at least one record, every record flag must * be correct, and the total length of the message must match * the length of the input data.<p> * This parser can handle chunked records, and converts them * into logical {@link NdefRecord}s within the message.<p> * Once the input data has been parsed to one or more logical * records, basic validation of the tnf, type, id, and payload fields * of each record is performed, as per the documentation on * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p> * If either strict validation of the binary format fails, or * basic validation during record construction fails, a * {@link FormatException} is thrown<p> * Deep inspection of the type, id and payload fields of * each record is not performed, so it is possible to parse input * that has a valid binary format and confirms to the basic * validation requirements of * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}, * but fails more strict requirements as specified by the * NFC Forum. * * <p class="note"> * It is safe to re-use the data byte array after construction: * this constructor will make an internal copy of all necessary fields. * * @param data raw bytes to parse * @throws FormatException if the data cannot be parsed */ public NdefMessage(byte[] data) throws FormatException { mRecords = null; // stop compiler complaints about final field if (parseNdefMessage(data) == -1) { throw new FormatException("Error while parsing NDEF message"); if (data == null) { throw new NullPointerException("null data"); } ByteBuffer buffer = ByteBuffer.wrap(data); mRecords = NdefRecord.parse(buffer, false); if (buffer.remaining() > 0) { throw new FormatException("trailing data"); } } /** * Construct an NDEF Message from one or more NDEF Records. * * @param record first record (mandatory) * @param records additional records (optional) */ public NdefMessage(NdefRecord record, NdefRecord ... records) { // validate if (record == null) { throw new NullPointerException("record cannot be null"); } for (NdefRecord r : records) { if (r == null) { throw new NullPointerException("record cannot be null"); } } mRecords = new NdefRecord[1 + records.length]; mRecords[0] = record; System.arraycopy(records, 0, mRecords, 1, records.length); } /** * Create an NDEF message from NDEF records. * Construct an NDEF Message from one or more NDEF Records. * * @param records one or more records */ public NdefMessage(NdefRecord[] records) { mRecords = new NdefRecord[records.length]; System.arraycopy(records, 0, mRecords, 0, records.length); // validate if (records.length < 1) { throw new IllegalArgumentException("must have at least one record"); } for (NdefRecord r : records) { if (r == null) { throw new NullPointerException("records cannot contain null"); } } mRecords = records; } /** * Get the NDEF records inside this NDEF message. * Get the NDEF Records inside this NDEF Message.<p> * An NDEF Message always has one or more NDEF Records. * * @return array of zero or more NDEF records. * @return array of one or more NDEF records. */ public NdefRecord[] getRecords() { return mRecords.clone(); return mRecords; } /** * Returns a byte array representation of this entire NDEF message. * Return this NDEF MEssage as raw bytes.<p> * The NDEF Message is formatted as per the NDEF 1.0 specification, * and the byte array is suitable for network transmission or storage * in an NFC Forum NDEF compatible tag.<p> * This method will not chunk any records, and will always use the * short record (SR) format and omit the identifier field when possible. * * @return NDEF Message in binary format */ public byte[] toByteArray() { //TODO: allocate the byte array once, copy each record once //TODO: process MB and ME flags outside loop if ((mRecords == null) || (mRecords.length == 0)) return new byte[0]; byte[] msg = {}; for (int i = 0; i < mRecords.length; i++) { byte[] record = mRecords[i].toByteArray(); byte[] tmp = new byte[msg.length + record.length]; /* Make sure the Message Begin flag is set only for the first record */ if (i == 0) { record[0] |= FLAG_MB; } else { record[0] &= ~FLAG_MB; } /* Make sure the Message End flag is set only for the last record */ if (i == (mRecords.length - 1)) { record[0] |= FLAG_ME; } else { record[0] &= ~FLAG_ME; int length = 0; for (NdefRecord r : mRecords) { length += r.getByteLength(); } System.arraycopy(msg, 0, tmp, 0, msg.length); System.arraycopy(record, 0, tmp, msg.length, record.length); ByteBuffer buffer = ByteBuffer.allocate(length); msg = tmp; for (int i=0; i<mRecords.length; i++) { boolean mb = (i == 0); // first record boolean me = (i == mRecords.length - 1); // last record mRecords[i].writeToByteBuffer(buffer, mb, me); } return msg; return buffer.array(); } @Override Loading Loading @@ -128,5 +208,26 @@ public final class NdefMessage implements Parcelable { } }; private native int parseNdefMessage(byte[] data); @Override public int hashCode() { return Arrays.hashCode(mRecords); } /** * Returns true if the specified NDEF Message contains * identical NDEF Records. */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; NdefMessage other = (NdefMessage) obj; return Arrays.equals(mRecords, other.mRecords); } @Override public String toString() { return "NdefMessage " + Arrays.toString(mRecords); } } No newline at end of file