Data formats supported by Android
Intent filter in Data Format
In the AndroidManifest. xml file Specify the resource file you created in the element:
<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHByZSBjbGFzcz0 = "brush: java;">... ...
Nfc_tech_filter.xml file (a Tag is considered to be matched only when all Tags match the nfc chip specified by the tech element in the tech-list element ):
android.nfc.tech.IsoDep
android.nfc.tech.NfcA
android.nfc.tech.NfcB
android.nfc.tech.NfcF
android.nfc.tech.NfcV
android.nfc.tech.Ndef
android.nfc.tech.NdefFormatable
android.nfc.tech.MifareClassic
android.nfc.tech.MifareUltralight
You can also create multiple resource files (multiple resource files are in the OR relationship, AND the chips in each resource file are in the AND relationship ):
android.nfc.tech.NfcA
android.nfc.tech.Ndef
android.nfc.tech.NdefFormatable
android.nfc.tech.Ndef
android.nfc.tech.NdefFormatable
Or create multiple Element (multiple The relationship between elements is OR, Element Is the AND relationship ):
android.nfc.tech.NfcA
android.nfc.tech.NfcB
android.nfc.tech.MifareClassic
You can view the data format supported by tags:
Use the Tag. getTechlist () method to obtain the data format supported by the Tag.
Obtain the unique ID of a Tag using the Tag. getId () method.
NfcAdapter = null: indicates that the device does not support NFC hardware.
NfcAdapter. isEnable () method: Determine whether NFC is enabled
To sum up:
A Tag obtains all the Tag types supported by the Tag. getTechlist () method. All resources The chips in are Tag tags. All the subsets that support tags are matched. You can write multiple , Each Is independent, as long as one of All All the chip types in the matching Tag support the chip is considered to be matched. Multiple Yes OR relationship, In Is the AND relationship.
Shape Structure of MifareClassic labels
Data Structure of MifareClassic labels
Note (assuming 1 K space ):
The first sector is generally used by the manufacturer to occupy blocks.
0-15 sectors: One slice corresponds to four blocks, so there are 64 blocks in total, with numbers 0-63 respectively. The first slice corresponds to 0-3 blocks, and the second slice corresponds: 4-7 blocks...
The last block of each slice is used to store the password or control bit. The rest is the data block. One block occupies 16 bytes. keyA occupies 6 bytes, the control bit occupies 4 bytes, and keyB occupies 6 bytes.
Common Methods for MifareClassic
Get (): gets the MifareClassic object based on the Tag object;
Connect (): allows I/O operations on MifareClassic labels;
GetType (): Obtain the specific type of the MifareClassic Tag: TYPE_CLASSIC, TYPE_PLUA, TYPE_PRO, TYPE_UNKNOWN;
GetSectorCount (): obtains the total number of slices of a tag;
GetBlockCount (): obtains the total number of blocks of a tag;
GetSize (): Obtain the tag capacity: SIZE_1K, SIZE_2K, SIZE_4K, SIZE_MINI
AuthenticateSectorWithKeyA (int SectorIndex, byte [] Key): Verify the KeyA password of the current sector. The return value is true or false.
Commonly used KeyA: default factory password: KEY_DEFAULT,
Suppliers of various purposes must cooperate with the MAD: KEY_MIFARE_APPLICATION_DIRECTORY of the technology.
Password formatted as NDEF: KEY_NFC_FORUM
GetBlockCountInSector (int): obtains the number of blocks contained in the current sector;
SectorToBlock (int): The block number of the first block of the current sector;
WriteBlock (int, data): writes data to the current block;
ReadBlock (int): Read the data of the current block.
Close (): IO operations on tags are prohibited to release resources.
Read/write process of MifareClassic labels
Get the Adapter object
Get Tag object
Obtain the MifareClassic object
Read data from data blocks
Connect (), readBlock (), close ()
Get the Adapter object
Get Tag object
Obtain the MifareClassic object
Write Data blocks to tags
Connect (), writeBlock (), close ()
Official documentation:
Working with tag technologies and the ACTION_TECH_DISCOVERED intent
When a device scans a tag that has NDEF data on it, but cocould not be mapped to a MIME or URI, the tag dispatch system tries to start an activity withACTION_TECH_DISCOVERED
Intent.ACTION_TECH_DISCOVERED
Is also used when a tag with non-NDEF data is scanned. having this fallback allows you to work with the data on the tag directly if the tag dispatch system cocould not parse it for you. the basic steps when working with tag technologies are as follows:
- Filter for
ACTION_TECH_DISCOVERED
Intent specifying the tag technologies that you want to handle. SeeFiltering for NFC intents for more information. In general, the tag dispatch system tries to startACTION_TECH_DISCOVERED
Intent when an NDEF message cannot be mapped to a MIME type or URI, or if the tag scanned did not contain NDEF data. for more information on how this is determined, see The Tag Dispatch System.
- When your application es the intent, obtain
Tag
Object from the intent:Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- Obtain an instance of
TagTechnology
, By calling one ofget
Factory methods of the classes inandroid.nfc.tech
Package. You can enumerate the supported technologies of the tag by callinggetTechList()
Before callingget
Factory method. For example, to obtain an instanceMifareUltralight
FromTag
, Do the following:MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
Reading and writing to tagsReading and writing to an NFC tag involves obtaining the tag from the intent and opening communication with the tag. you must define your own protocol stack to read and write data to the tag. keep in mind, however, that you can still read and write NDEF data when working directly with a tag. it is up to you how you want to structure things. the following example shows how to work with a MIFARE Ultralight tag.
package com.example.android.nfc;import android.nfc.Tag;import android.nfc.tech.MifareUltralight;import android.util.Log;import java.io.IOException;import java.nio.charset.Charset;public class MifareUltralightTagTester { private static final String TAG = MifareUltralightTagTester.class.getSimpleName(); public void writeTag(Tag tag, String tagText) { MifareUltralight ultralight = MifareUltralight.get(tag); try { ultralight.connect(); ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII"))); } catch (IOException e) { Log.e(TAG, "IOException while closing MifareUltralight...", e); } finally { try { ultralight.close(); } catch (IOException e) { Log.e(TAG, "IOException while closing MifareUltralight...", e); } } } public String readTag(Tag tag) { MifareUltralight mifare = MifareUltralight.get(tag); try { mifare.connect(); byte[] payload = mifare.readPages(4); return new String(payload, Charset.forName("US-ASCII")); } catch (IOException e) { Log.e(TAG, "IOException while writing MifareUltralight message...", e); } finally { if (mifare != null) { try { mifare.close(); } catch (IOException e) { Log.e(TAG, "Error closing tag...", e); } } } return null; }}
Example program:
MainActivity:Package mobile. android. mifareultralight; import java. io. IOException; import java. nio. charset. charset; import android. app. activity; import android. app. pendingIntent; import android. content. intent; import android. nfc. nfcAdapter; import android. nfc. tag; import android. nfc. tech. mifareClassic; import android. OS. bundle; import android. util. log; import android. widget. checkBox; import android. widget. toast; public class MifareultralightMainActivity extends Activity {private CheckBox mWriteData; private NfcAdapter mNfcAdapter; private PendingIntent mPendingIntent; @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_mifareultralight); mWriteData = (CheckBox) findViewById (R. id. checkbox_write); mNfcAdapter = mNfcAdapter. getdefaadapter adapter (t His); if (mNfcAdapter = null) {Toast. makeText (this, "the device does not support NFC! ", Toast. LENGTH_LONG). show (); finish (); return;} if (! MNfcAdapter. isEnabled () {Toast. makeText (this, "enable NFC in system settings first! ", Toast. LENGTH_LONG ). show (); finish (); return;} mPendingIntent = PendingIntent. getActivity (this, 0, new Intent (this, getClass (), 0) ;}@ Override public void onResume () {super. onResume (); if (mNfcAdapter! = Null) mNfcAdapter. enableForegroundDispatch (this, mPendingIntent, null, null) ;}@ Override public void onNewIntent (Intent intent) {Tag tag = intent. getParcelableExtra (mNfcAdapter. EXTRA_TAG); String [] techList = tag. getTechList (); boolean haveMifareUltralight = false; for (String tech: techList) {if (tech. indexOf ("MifareClassic")> = 0) {haveMifareUltralight = true; break ;}} if (! HaveMifareUltralight) {Toast. makeText (this, "MifareClassic not supported", Toast. LENGTH_LONG ). show (); return;} if (mWriteData. isChecked () {writeTag (tag);} else {String data = readTag (tag); if (data! = Null) {Log. I (data, "ouput"); Toast. makeText (this, data, Toast. LENGTH_LONG ). show () ;}}@ Override public void onPause () {super. onPause (); if (mNfcAdapter! = Null) mNfcAdapter. disableForegroundDispatch (this);} public void writeTag (Tag tag) {MifareClassic mfc = MifareClassic. get (tag); try {mfc. connect (); boolean auth = false; short sectorAddress = 1; auth = mfc. authenticateSectorWithKeyA (sectorAddress, MifareClassic. KEY_NFC_FORUM); if (auth) {// the last block of the sector is used for KeyA and KeyB cannot be overwritted mfc. writeBlock (4, "13138384" 38000000 ". getBytes (); mfc. writeBlock (5, "1322676888000000 ". getBytes (); mfc. close (); Toast. makeText (this, "Write successful", Toast. LENGTH_SHORT ). show () ;}} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();} finally {try {mfc. close ();} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace () ;}}// convert the Character Sequence to a hexadecimal String private String bytesToHexString (byte [] Src) {StringBuilder stringBuilder = new StringBuilder ("0x"); if (src = null | src. length <= 0) {return null;} char [] buffer = new char [2]; for (int I = 0; I <src. length; I ++) {buffer [0] = Character. forDigit (src [I] >>> 4) & 0x0F, 16); buffer [1] = Character. forDigit (src [I] & 0x0F, 16); System. out. println (buffer); stringBuilder. append (buffer);} return stringBuilder. toString ();} public Str Ing readTag (Tag tag) {MifareClassic mfc = MifareClassic. get (tag); for (String tech: tag. getTechList () {System. out. println (tech);} boolean auth = false; // read TAG try {String metaInfo = ""; // Enable I/O operations to the tag from this TagTechnology object. mfc. connect (); int type = mfc. getType (); // The type of the obtained TAG int sectorCount = mfc. getSectorCount (); // obtain the number of slice contained in the TAG String typeS = ""; switch (type ){ Case MifareClassic. TYPE_CLASSIC: typeS = "TYPE_CLASSIC"; break; case MifareClassic. TYPE_PLUS: typeS = "TYPE_PLUS"; break; case MifareClassic. TYPE_PRO: typeS = "TYPE_PRO"; break; case MifareClassic. TYPE_UNKNOWN: typeS = "TYPE_UNKNOWN"; break;} metaInfo + = "card type:" + typeS + "\ n total" + sectorCount + "slice \ n total" + mfc. getBlockCount () + "Block \ n storage space:" + mfc. getSize () + "B \ n"; for (int j = 0; j <sectorCount; J ++) {// Authenticate a sector with key. auth = mfc. authenticateSectorWithKeyA (j, MifareClassic. KEY_NFC_FORUM); int bCount; int bIndex; if (auth) {metaInfo + = "Sector" + j + ": Verification Successful \ n "; // read the block bCount = mfc in the slice. getBlockCountInSector (j); bIndex = mfc. sectorToBlock (j); for (int I = 0; I <bCount; I ++) {byte [] data = mfc. readBlock (bIndex); metaInfo + = "Block" + bIndex + ":" + bytesToHexString (d Ata) + "\ n"; bIndex ++ ;}} else {metaInfo + = "Sector" + j + ": Verification Failed \ n" ;}} return metaInfo ;} catch (Exception e) {Toast. makeText (this, e. getMessage (), Toast. LENGTH_LONG ). show (); e. printStackTrace ();} finally {if (mfc! = Null) {try {mfc. close ();} catch (IOException e) {Toast. makeText (this, e. getMessage (), Toast. LENGTH_LONG ). show () ;}} return null ;}}
Configuration file: