public final class MifareClassic extends Object
Tag
.
Acquire a MifareClassic
object using get(android.nfc.Tag)
.
MIFARE Classic is also known as MIFARE Standard.
MIFARE Classic tags are divided into sectors, and each sector is sub-divided into
blocks. Block size is always 16 bytes (BLOCK_SIZE
. Sector size varies.
SIZE_MINI
), with 5 sectors each of 4 blocks.
SIZE_1K
), with 16 sectors each of 4 blocks.
SIZE_2K
), with 32 sectors each of 4 blocks.
SIZE_4K
). The first 32 sectors contain 4 blocks
and the last 8 sectors contain 16 blocks.
MIFARE Classic tags require authentication on a per-sector basis before any
other I/O operations on that sector can be performed. There are two keys per sector,
and ACL bits determine what I/O operations are allowed on that sector after
authenticating with a key. authenticateSectorWithKeyA(int, byte[])
and
authenticateSectorWithKeyB(int, byte[])
.
Three well-known authentication keys are defined in this class:
KEY_DEFAULT
, KEY_MIFARE_APPLICATION_DIRECTORY
,
KEY_NFC_FORUM
.
KEY_DEFAULT
is the default factory key for MIFARE Classic.
KEY_MIFARE_APPLICATION_DIRECTORY
is the well-known key for
MIFARE Classic cards that have been formatted according to the
MIFARE Application Directory (MAD) specification.
KEY_NFC_FORUM
is the well-known key for MIFARE Classic cards that
have been formatted according to the NXP specification for NDEF on MIFARE Classic.
Implementation of this class on a Android NFC device is optional.
If it is not implemented, then
MifareClassic
will never be enumerated in Tag.getTechList()
.
If it is enumerated, then all MifareClassic
I/O operations will be supported,
and Ndef.MIFARE_CLASSIC
NDEF tags will also be supported. In either case,
NfcA
will also be enumerated on the tag, because all MIFARE Classic tags are also
NfcA
.
Note: Methods that perform I/O operations
require the android.Manifest.permission#NFC
permission.
Modifier and Type | Field and Description |
---|---|
static int |
BLOCK_SIZE
Size of a MIFARE Classic block (in bytes)
|
static byte[] |
KEY_DEFAULT
The default factory key.
|
static byte[] |
KEY_MIFARE_APPLICATION_DIRECTORY
The well-known key for tags formatted according to the
MIFARE Application Directory (MAD) specification.
|
static byte[] |
KEY_NFC_FORUM
The well-known key for tags formatted according to the
NDEF on MIFARE Classic specification.
|
static int |
SIZE_1K
Tag contains 16 sectors, each with 4 blocks.
|
static int |
SIZE_2K
Tag contains 32 sectors, each with 4 blocks.
|
static int |
SIZE_4K
Tag contains 40 sectors.
|
static int |
SIZE_MINI
Tag contains 5 sectors, each with 4 blocks.
|
static int |
TYPE_CLASSIC
A MIFARE Classic tag
|
static int |
TYPE_PLUS
A MIFARE Plus tag
|
static int |
TYPE_PRO
A MIFARE Pro tag
|
static int |
TYPE_UNKNOWN
A MIFARE Classic compatible card of unknown type
|
ISO_DEP, MIFARE_CLASSIC, MIFARE_ULTRALIGHT, NDEF, NDEF_FORMATABLE, NFC_A, NFC_B, NFC_BARCODE, NFC_F, NFC_V
Constructor and Description |
---|
MifareClassic(Tag tag) |
Modifier and Type | Method and Description |
---|---|
boolean |
authenticateSectorWithKeyA(int sectorIndex,
byte[] key)
Authenticate a sector with key A.
|
boolean |
authenticateSectorWithKeyB(int sectorIndex,
byte[] key)
Authenticate a sector with key B.
|
int |
blockToSector(int blockIndex)
Return the sector that contains a given block.
|
void |
close()
Disable I/O operations to the tag from this
TagTechnology object, and release resources. |
void |
connect()
Enable I/O operations to the tag from this
TagTechnology object. |
void |
decrement(int blockIndex,
int value)
Decrement a value block, storing the result in the temporary block on the tag.
|
static MifareClassic |
get(Tag tag)
Get an instance of
MifareClassic for the given tag. |
int |
getBlockCount()
Return the total number of MIFARE Classic blocks.
|
int |
getBlockCountInSector(int sectorIndex)
Return the number of blocks in the given sector.
|
int |
getMaxTransceiveLength()
Return the maximum number of bytes that can be sent with
transceive(byte[]) . |
int |
getSectorCount()
Return the number of MIFARE Classic sectors.
|
int |
getSize()
|
Tag |
getTag()
Get the
Tag object backing this TagTechnology object. |
int |
getTimeout()
Get the current
transceive(byte[]) timeout in milliseconds. |
int |
getType()
Return the type of this MIFARE Classic compatible tag.
|
void |
increment(int blockIndex,
int value)
Increment a value block, storing the result in the temporary block on the tag.
|
boolean |
isConnected()
Helper to indicate if I/O operations should be possible.
|
boolean |
isEmulated()
Return true if the tag is emulated, determined at discovery time.
|
byte[] |
readBlock(int blockIndex)
Read 16-byte block.
|
void |
reconnect()
Re-connect to the
Tag associated with this connection. |
void |
restore(int blockIndex)
Copy from a value block to the temporary block.
|
int |
sectorToBlock(int sectorIndex)
Return the first block of a given sector.
|
void |
setTimeout(int timeout)
Set the
transceive(byte[]) timeout in milliseconds. |
byte[] |
transceive(byte[] data)
Send raw NfcA data to a tag and receive the response.
|
void |
transfer(int blockIndex)
Copy from the temporary block to a value block.
|
void |
writeBlock(int blockIndex,
byte[] data)
Write 16-byte block.
|
public static final byte[] KEY_DEFAULT
public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY
public static final byte[] KEY_NFC_FORUM
public static final int TYPE_UNKNOWN
public static final int TYPE_CLASSIC
public static final int TYPE_PLUS
public static final int TYPE_PRO
public static final int SIZE_1K
public static final int SIZE_2K
public static final int SIZE_4K
public static final int SIZE_MINI
public static final int BLOCK_SIZE
public MifareClassic(Tag tag) throws RemoteException
RemoteException
public static MifareClassic get(Tag tag)
MifareClassic
for the given tag.
Does not cause any RF activity and does not block.
Returns null if MifareClassic
was not enumerated in Tag.getTechList()
.
This indicates the tag is not MIFARE Classic compatible, or this Android
device does not support MIFARE Classic.
tag
- an MIFARE Classic compatible tagpublic int getType()
One of TYPE_UNKNOWN
, TYPE_CLASSIC
, TYPE_PLUS
or
TYPE_PRO
.
Does not cause any RF activity and does not block.
public int getSize()
One of SIZE_MINI
, SIZE_1K
, SIZE_2K
, SIZE_4K
.
These constants are equal to their respective size in bytes.
Does not cause any RF activity and does not block.
public boolean isEmulated()
public int getSectorCount()
Does not cause any RF activity and does not block.
public int getBlockCount()
Does not cause any RF activity and does not block.
public int getBlockCountInSector(int sectorIndex)
Does not cause any RF activity and does not block.
sectorIndex
- index of sector, starting from 0public int blockToSector(int blockIndex)
Does not cause any RF activity and does not block.
blockIndex
- index of block to lookup, starting from 0public int sectorToBlock(int sectorIndex)
Does not cause any RF activity and does not block.
sectorIndex
- index of sector to lookup, starting from 0public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException
Successful authentication of a sector with key A enables other
I/O operations on that sector. The set of operations granted by key A
key depends on the ACL bits set in that sector. For more information
see the MIFARE Classic specification on http://www.nxp.com
.
A failed authentication attempt causes an implicit reconnection to the tag, so authentication to other sectors will be lost.
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
sectorIndex
- index of sector to authenticate, starting from 0key
- 6-byte authentication keyTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException
Successful authentication of a sector with key B enables other
I/O operations on that sector. The set of operations granted by key B
depends on the ACL bits set in that sector. For more information
see the MIFARE Classic specification on http://www.nxp.com
.
A failed authentication attempt causes an implicit reconnection to the tag, so authentication to other sectors will be lost.
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
sectorIndex
- index of sector to authenticate, starting from 0key
- 6-byte authentication keyTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic byte[] readBlock(int blockIndex) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to read, starting from 0TagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic void writeBlock(int blockIndex, byte[] data) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to write, starting from 0data
- 16 bytes of data to writeTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic void increment(int blockIndex, int value) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to increment, starting from 0value
- non-negative to increment byTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic void decrement(int blockIndex, int value) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to decrement, starting from 0value
- non-negative to decrement byTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic void transfer(int blockIndex) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to copy toTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic void restore(int blockIndex) throws IOException
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
blockIndex
- index of block to copy fromTagLostException
- if the tag leaves the fieldIOException
- if there is an I/O failure, or the operation is canceledpublic byte[] transceive(byte[] data) throws IOException
This is equivalent to connecting to this tag via NfcA
and calling NfcA.transceive(byte[])
. Note that all MIFARE Classic
tags are based on NfcA
technology.
Use getMaxTransceiveLength()
to retrieve the maximum number of bytes
that can be sent with transceive(byte[])
.
This is an I/O operation and will block until complete. It must
not be called from the main application thread. A blocked call will be canceled with
IOException
if close()
is called from another thread.
Requires the android.Manifest.permission#NFC
permission.
IOException
NfcA.transceive(byte[])
public int getMaxTransceiveLength()
transceive(byte[])
.transceive(byte[])
.public void setTimeout(int timeout)
transceive(byte[])
timeout in milliseconds.
The timeout only applies to transceive(byte[])
on this object,
and is reset to a default value when close()
is called.
Setting a longer timeout may be useful when performing transactions that require a long processing time on the tag such as key generation.
Requires the android.Manifest.permission#NFC
permission.
timeout
- timeout value in millisecondspublic int getTimeout()
transceive(byte[])
timeout in milliseconds.
Requires the android.Manifest.permission#NFC
permission.
public Tag getTag()
TagTechnology
Tag
object backing this TagTechnology
object.getTag
in interface TagTechnology
Tag
backing this TagTechnology
object.public boolean isConnected()
TagTechnology
Returns true if TagTechnology.connect()
has completed, and TagTechnology.close()
has not been
called, and the Tag
is not known to be out of range.
Does not cause RF activity, and does not block.
isConnected
in interface TagTechnology
public void connect() throws IOException
TagTechnology
TagTechnology
object.
May cause RF activity and may block. Must not be called
from the main application thread. A blocked call will be canceled with
IOException
by calling TagTechnology.close()
from another thread.
Only one TagTechnology
object can be connected to a Tag
at a time.
Applications must call TagTechnology.close()
when I/O operations are complete.
Requires the android.Manifest.permission#NFC
permission.
connect
in interface TagTechnology
IOException
- if there is an I/O failure, or connect is canceledTagTechnology.close()
public void reconnect() throws IOException
TagTechnology
Tag
associated with this connection. Reconnecting to a tag can be
used to reset the state of the tag itself.
May cause RF activity and may block. Must not be called
from the main application thread. A blocked call will be canceled with
IOException
by calling TagTechnology.close()
from another thread.
Requires the android.Manifest.permission#NFC
permission.
reconnect
in interface TagTechnology
IOException
- if there is an I/O failure, or connect is canceledTagTechnology.connect()
,
TagTechnology.close()
public void close() throws IOException
TagTechnology
TagTechnology
object, and release resources.
Also causes all blocked I/O operations on other thread to be canceled and
return with IOException
.
Requires the android.Manifest.permission#NFC
permission.
close
in interface TagTechnology
close
in interface Closeable
close
in interface AutoCloseable
IOException
- if an I/O error occursTagTechnology.connect()