public final class NdefRecord extends Object implements Parcelable
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.
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.
This class represents logical (complete) NDEF Records, and can not be
used to represent chunked (partial) NDEF Records. However
NdefMessage.NdefMessage(byte[])
can be used to parse a message
containing chunked records, and will return a message with unchunked
(complete) records.
A logical NDEF Record always contains a 3-bit TNF (Type Name Field) that provides high level typing for the rest of the record. The remaining fields are variable length and not always present:
Helpers such as createUri(android.net.Uri)
, createMime(java.lang.String, byte[])
and createExternal(java.lang.String, java.lang.String, byte[])
are included to create well-formatted
NDEF Records with correctly set tnf, type, id and payload fields, please
use these helpers whenever possible.
Use the constructor NdefRecord(short, byte[], byte[], byte[])
if you know what you are doing and what to set the fields individually.
Only basic validation is performed with this constructor, so it is possible
to create records that do not confirm to the strict NFC Forum
specifications.
The binary representation of an NDEF Record includes additional flags to
indicate location with an NDEF message, provide support for chunking of
NDEF records, and to pack optional fields. This class does not expose
those details. To write an NDEF Record as binary you must first put it
into an NdefMessage
, then call NdefMessage.toByteArray()
.
NdefMessage
and NdefRecord
implementations are
always available, even on Android devices that do not have NFC hardware.
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.
NfcAdapter.ACTION_NDEF_DISCOVERED
,
NdefMessage
Parcelable.ClassLoaderCreator<T>, Parcelable.Creator<T>
Modifier and Type | Field and Description |
---|---|
static Parcelable.Creator<NdefRecord> |
CREATOR |
static byte[] |
RTD_ALTERNATIVE_CARRIER
RTD Alternative Carrier type.
|
static byte[] |
RTD_ANDROID_APP
RTD Android app type.
|
static byte[] |
RTD_HANDOVER_CARRIER
RTD Handover Carrier type.
|
static byte[] |
RTD_HANDOVER_REQUEST
RTD Handover Request type.
|
static byte[] |
RTD_HANDOVER_SELECT
RTD Handover Select type.
|
static byte[] |
RTD_SMART_POSTER
RTD Smart Poster type.
|
static byte[] |
RTD_TEXT
RTD Text type.
|
static byte[] |
RTD_URI
RTD URI type.
|
static short |
TNF_ABSOLUTE_URI
Indicates the type field contains an absolute-URI
BNF construct defined by RFC 3986.
|
static short |
TNF_EMPTY
Indicates the record is empty.
|
static short |
TNF_EXTERNAL_TYPE
Indicates the type field contains an external type name.
|
static short |
TNF_MIME_MEDIA
Indicates the type field contains a media-type BNF
construct, defined by RFC 2046.
|
static short |
TNF_RESERVED
Reserved TNF type.
|
static short |
TNF_UNCHANGED
Indicates the payload is an intermediate or final chunk of a chunked
NDEF Record.
|
static short |
TNF_UNKNOWN
Indicates the payload type is unknown.
|
static short |
TNF_WELL_KNOWN
Indicates the type field contains a well-known RTD type name.
|
CONTENTS_FILE_DESCRIPTOR, PARCELABLE_WRITE_RETURN_VALUE
Constructor and Description |
---|
NdefRecord(byte[] data)
Deprecated.
use
NdefMessage.NdefMessage(byte[]) instead. |
NdefRecord(short tnf,
byte[] type,
byte[] id,
byte[] payload)
Construct an NDEF Record from its component fields.
|
Modifier and Type | Method and Description |
---|---|
static NdefRecord |
createApplicationRecord(String packageName)
Create a new Android Application Record (AAR).
|
static NdefRecord |
createExternal(String domain,
String type,
byte[] data)
Create a new NDEF Record containing external (application-specific) data.
|
static NdefRecord |
createMime(String mimeType,
byte[] mimeData)
Create a new NDEF Record containing MIME data.
|
static NdefRecord |
createUri(String uriString)
Create a new NDEF Record containing a URI.
|
static NdefRecord |
createUri(Uri uri)
Create a new NDEF Record containing a URI.
|
int |
describeContents()
Describe the kinds of special objects contained in this Parcelable's
marshalled representation.
|
boolean |
equals(Object obj)
Returns true if the specified NDEF Record contains
identical tnf, type, id and payload fields.
|
byte[] |
getId()
Returns the variable length ID.
|
byte[] |
getPayload()
Returns the variable length payload.
|
short |
getTnf()
Returns the 3-bit TNF.
|
byte[] |
getType()
Returns the variable length Type field.
|
int |
hashCode()
Returns an integer hash code for this object.
|
byte[] |
toByteArray()
Deprecated.
use
NdefMessage.toByteArray() instead |
String |
toMimeType()
Map this record to a MIME type, or return null if it cannot be mapped.
|
String |
toString()
Returns a string containing a concise, human-readable description of this
object.
|
Uri |
toUri()
Map this record to a URI, or return null if it cannot be mapped.
|
void |
writeToParcel(Parcel dest,
int flags)
Flatten this object in to a Parcel.
|
public static final short TNF_EMPTY
Type, id and payload fields are empty in a TNF_EMPTY record.
public static final short TNF_WELL_KNOWN
public static final short TNF_MIME_MEDIA
Use this with MIME type names such as "image/jpeg", or
using the helper createMime(java.lang.String, byte[])
.
public static final short TNF_ABSOLUTE_URI
When creating new records prefer createUri(android.net.Uri)
,
since it offers more compact URI encoding
(#RTD_URI allows compression of common URI prefixes).
public static final short TNF_EXTERNAL_TYPE
Used to encode custom payloads. When creating new records
use the helper createExternal(java.lang.String, java.lang.String, byte[])
.
The external-type RTD format is specified in NFCForum-TS-RTD_1.0.
Note this TNF should not be used with RTD_TEXT or RTD_URI constants. Those are well known RTD constants, not external RTD constants.
public static final short TNF_UNKNOWN
NFC Forum explains this should be treated similarly to the "application/octet-stream" MIME type. The payload type is not explicitly encoded within the record.
The type field is empty in an TNF_UNKNOWN record.
public static final short TNF_UNCHANGED
TNF_UNCHANGED can not be used with this class
since all NdefRecord
s are already unchunked, however they
may appear in the binary format.
public static final short TNF_RESERVED
The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this value like TNF_UNKNOWN.
public static final byte[] RTD_TEXT
TNF_WELL_KNOWN
public static final byte[] RTD_URI
TNF_WELL_KNOWN
public static final byte[] RTD_SMART_POSTER
TNF_WELL_KNOWN
public static final byte[] RTD_ALTERNATIVE_CARRIER
TNF_WELL_KNOWN
public static final byte[] RTD_HANDOVER_CARRIER
TNF_WELL_KNOWN
public static final byte[] RTD_HANDOVER_REQUEST
TNF_WELL_KNOWN
public static final byte[] RTD_HANDOVER_SELECT
TNF_WELL_KNOWN
public static final byte[] RTD_ANDROID_APP
The payload of a record with type RTD_ANDROID_APP
should be the package name identifying an application.
Multiple RTD_ANDROID_APP records may be included
in a single NdefMessage
.
Use createApplicationRecord(String)
to create
RTD_ANDROID_APP records.
public static final Parcelable.Creator<NdefRecord> CREATOR
public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload)
Recommend to use helpers such as {#createUri} or
{createExternal(java.lang.String, java.lang.String, byte[])
where possible, since they perform
stricter validation that the record is correctly formatted
as per NDEF specifications. However if you know what you are
doing then this constructor offers the most flexibility.
An NdefRecord
represents a logical (complete)
record, and cannot represent NDEF Record chunks.
Basic validation of the tnf, type, id and payload is performed as per the following rules:
TNF_EMPTY
cannot have a type,
id or payload.TNF_UNKNOWN
or 0x07
cannot have a type.TNF_UNCHANGED
are not allowed
since this class only represents complete (unchunked) records.
If any of the above validation
steps fail then IllegalArgumentException
is thrown.
Deep inspection of the type, id and payload fields is not performed, so it is possible to create NDEF Records that conform to section 3.2.6 but fail other more strict NDEF specification requirements. For example, the payload may be invalid given the tnf and type.
To omit a type, id or payload field, set the parameter to an empty byte array or null.
tnf
- a 3-bit TNF constanttype
- byte array, containing zero to 255 bytes, or nullid
- byte array, containing zero to 255 bytes, or nullpayload
- byte array, containing zero to (2 ** 32 - 1) bytes,
or nullIllegalArugmentException
- if a valid record cannot be created@Deprecated public NdefRecord(byte[] data) throws FormatException
NdefMessage.NdefMessage(byte[])
instead.
This method is deprecated, use NdefMessage.NdefMessage(byte[])
instead. This is because it does not make sense to parse a record:
the NDEF binary format is only defined for a message, and the
record flags MB and ME do not make sense outside of the context of
an entire message.
This implementation will attempt to parse a single record by ignoring
the MB and ME flags, and otherwise following the rules of
NdefMessage.NdefMessage(byte[])
.
data
- raw bytes to parseFormatException
- if the data cannot be parsed into a valid recordpublic static NdefRecord createApplicationRecord(String packageName)
This record indicates to other Android devices the package that should be used to handle the entire NDEF message. You can embed this record anywhere into your message to ensure that the intended package receives the message.
When an Android device dispatches an NdefMessage
containing one or more Android application records,
the applications contained in those records will be the
preferred target for the NfcAdapter.ACTION_NDEF_DISCOVERED
intent, in the order in which they appear in the message.
This dispatch behavior was first added to Android in
Ice Cream Sandwich.
If none of the applications have a are installed on the device, a Market link will be opened to the first application.
Note that Android application records do not overrule
applications that have called
NfcAdapter.enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][])
.
packageName
- Android package namepublic static NdefRecord createUri(Uri uri)
Use this method to encode a URI (or URL) into an NDEF Record.
Uses the well known URI type representation: TNF_WELL_KNOWN
and RTD_URI
. This is the most efficient encoding
of a URI into NDEF.
The uri parameter will be normalized with
Uri.normalizeScheme()
to set the scheme to lower case to
follow Android best practices for intent filtering.
However the unchecked exception
IllegalArgumentException
may be thrown if the uri
parameter has serious problems, for example if it is empty, so always
catch this exception if you are passing user-generated data into this
method.
Reference specification: NFCForum-TS-RTD_URI_1.0
uri
- URI to encode.IllegalArugmentException
- if the uri is empty or invalidpublic static NdefRecord createUri(String uriString)
Use this method to encode a URI (or URL) into an NDEF Record.
Uses the well known URI type representation: TNF_WELL_KNOWN
and RTD_URI
. This is the most efficient encoding
of a URI into NDEF.
The uriString parameter will be normalized with
Uri.normalizeScheme()
to set the scheme to lower case to
follow Android best practices for intent filtering.
However the unchecked exception
IllegalArgumentException
may be thrown if the uriString
parameter has serious problems, for example if it is empty, so always
catch this exception if you are passing user-generated data into this
method.
Reference specification: NFCForum-TS-RTD_URI_1.0
uriString
- string URI to encode.IllegalArugmentException
- if the uriString is empty or invalidpublic static NdefRecord createMime(String mimeType, byte[] mimeData)
Use this method to encode MIME-typed data into an NDEF Record, such as "text/plain", or "image/jpeg".
The mimeType parameter will be normalized with
Intent.normalizeMimeType(java.lang.String)
to follow Android best
practices for intent filtering, for example to force lower-case.
However the unchecked exception
IllegalArgumentException
may be thrown
if the mimeType parameter has serious problems,
for example if it is empty, so always catch this
exception if you are passing user-generated data into this method.
For efficiency, This method might not make an internal copy of the mimeData byte array, so take care not to modify the mimeData byte array while still using the returned NdefRecord.
mimeType
- a valid MIME typemimeData
- MIME data as bytesIllegalArugmentException
- if the mimeType is empty or invalidpublic static NdefRecord createExternal(String domain, String type, byte[] data)
Use this method to encode application specific data into an NDEF Record. The data is typed by a domain name (usually your Android package name) and a domain-specific type. This data is packaged into a "NFC Forum External Type" NDEF Record.
NFC Forum requires that the domain and type used in an external record are treated as case insensitive, however Android intent filtering is always case sensitive. So this method will force the domain and type to lower-case before creating the NDEF Record.
The unchecked exception IllegalArgumentException
will be thrown
if the domain and type have serious problems, for example if either field
is empty, so always catch this
exception if you are passing user-generated data into this method.
There are no such restrictions on the payload data.
For efficiency, This method might not make an internal copy of the data byte array, so take care not to modify the data byte array while still using the returned NdefRecord. Reference specification: NFCForum-TS-RTD_1.0
domain
- domain-name of issuing organizationtype
- domain-specific type of datadata
- payload as bytesIllegalArugmentException
- if either domain or type are empty or invalidpublic short getTnf()
TNF is the top-level type.
public byte[] getType()
This should be used in conjunction with the TNF field to determine the payload format.
Returns an empty byte array if this record does not have a type field.
public byte[] getId()
Returns an empty byte array if this record does not have an id field.
public byte[] getPayload()
Returns an empty byte array if this record does not have a payload field.
@Deprecated public byte[] toByteArray()
NdefMessage.toByteArray()
instead
This method is deprecated, use NdefMessage.toByteArray()
instead. This is because the NDEF binary format is not defined for
a record outside of the context of a message: the MB and ME flags
cannot be set without knowing the location inside a message.
This implementation will attempt to serialize a single record by always setting the MB and ME flags (in other words, assume this is a single-record NDEF Message).
public String toMimeType()
Currently this method considers all TNF_MIME_MEDIA
records to
be MIME records, as well as some TNF_WELL_KNOWN
records such as
RTD_TEXT
. If this is a MIME record then the MIME type as string
is returned, otherwise null is returned.
This method does not perform validation that the MIME type is actually valid. It always attempts to return a string containing the type if this is a MIME record.
The returned MIME type will by normalized to lower-case using
Intent.normalizeMimeType(java.lang.String)
.
The MIME payload can be obtained using getPayload()
.
public Uri toUri()
Currently this method considers the following to be URI records:
TNF_ABSOLUTE_URI
records.TNF_WELL_KNOWN
with a type of RTD_URI
.TNF_WELL_KNOWN
with a type of RTD_SMART_POSTER
and containing a URI record in the NDEF message nested in the payload.
TNF_EXTERNAL_TYPE
records.This method does not perform validation that the URI is actually valid: it always attempts to create and return a URI if this record appears to be a URI record by the above rules.
The returned URI will be normalized to have a lower case scheme
using Uri.normalizeScheme()
.
public int describeContents()
Parcelable
describeContents
in interface Parcelable
public void writeToParcel(Parcel dest, int flags)
Parcelable
writeToParcel
in interface Parcelable
dest
- The Parcel in which the object should be written.flags
- Additional flags about how the object should be written.
May be 0 or Parcelable.PARCELABLE_WRITE_RETURN_VALUE
.public int hashCode()
Object
Object.equals(java.lang.Object)
returns true
must return
the same hash code value. This means that subclasses of Object
usually override both methods or neither method.
Note that hash values must not change over time unless information used in equals comparisons also changes.
See Writing a correct
hashCode
method
if you intend implementing your own hashCode
method.
hashCode
in class Object
Object.equals(java.lang.Object)
public boolean equals(Object obj)
equals
in class Object
obj
- the object to compare this instance with.true
if the specified object is equal to this Object
; false
otherwise.Object.hashCode()
public String toString()
Object
getClass().getName() + '@' + Integer.toHexString(hashCode())
See Writing a useful
toString
method
if you intend implementing your own toString
method.