Android NFC Development
Let's talk about NFC Development Summary, read NFC development materials for a few days, and collect a lot of information about this, demos, and other people's summaries. The following is an excerpt from the summary. If so, the code is provided. I also have a demo. I need to send an email to me in the comments.
I. NFC configuration Summary
First, the screen is not locked. Second, the NFC function is enabled in settings.
When the system detects an NFC tag, it automatically finds the most suitable activity to process the intent.
The Intent sent by NFC has three actions:
ACTION_NDEF_DISCOVERED: when the system detects that the tag contains data in the NDEF format and the system has activity declarations that can accept Intent containing the NDEF data, the system will give priority to the intent of this action.
ACTION_TECH_DISCOVERED: when no activity declares that it can respond to ACTION_NDEF_DISCOVERED, the system will try to issue TECH intent. even if the data contained in your tag is NDEF, if the MIMEtype or URI of the data cannot match the data declared by any activity, similarly, the system will try to generate a tech-format intent instead of NDEF.
ACTION_TAG_DISCOVERED: when no one in the system accepts the first two intents, the default TAG type
Ii. NFC-related androidManifest File Settings
First, permission:
Next, the sdk-level limit: I personally suggest that API11 should be more appropriate:
If it is API8, the Code set by the nfc function will go wrong and will be thrown
For example:
NfcAdapter mAdapter = NfcAdapter. getdefaadapter adapter (this );
MAdapter. isEnabled ()
Then there are special functional limitations:
This life enables your applications to be declared on googleplay that users must have nfc functions.
3. NFC tag filtering, which is also set in the androidManifest File
In the intent filter xml Declaration of the activity, you can declare and filter the three actions at the same time. however, as mentioned earlier, you should know that the system has a priority when sending intent, so you 'd better know which one you want to handle most.
1: Filter ACTION_TAG_DISCOVERED:
This is the simplest option and the last option to be tried to accept intent.
2: Filter ACTION_NDEF_DISCOVERED:
The most important one is the mimeType type of data. The more accurate the definition is, the higher the success rate of intent pointing to your activity. Otherwise, the system may not issue the NDEF intent you want. The following example shows how to use NDEF to write NFC tags.
3: Filter ACTION_TECH_DISCOVERED:
First, you need Create a filter rule file under/res/xml. Name. For example, it can be nfc_tech_filter.xml. This defines various nfc standards. each nfc card meets multiple different standards. I personally think these standards are compatible with each other. After detecting the nfc tag, you can use the getTechList () method to check which nfc standards are supported by the tag you are detecting.
One nfc_tech_filter.xml can define multiple Structure Group.
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
An example of declaring xml Filtering in the androidManifest file is as follows:
4. Check the specific code:
1. The main code is as follows:
Package org. reno. beam; import java. io. byteArrayOutputStream; import java. nio. charset. charset; import java. text. dateFormat; import java. text. simpleDateFormat; import java. util. date; import java. util. list; import java. util. locale; import org. nfc. read. parsedNdefRecord; import android. app. activity; import android. app. alertDialog; import android. app. pendingIntent; import android. content. dialogInterface; import andro Id. content. intent; import android. nfc. ndefMessage; import android. nfc. ndefRecord; import android. nfc. nfcAdapter; import android. nfc. tag; import android. nfc. tech. mifareClassic; import android. nfc. tech. mifareUltralight; import android. OS. bundle; import android. OS. parcelable; import android. provider. settings; import android. widget. textView; public class MainActivity extends Activity {private static final DateFo Rmat TIME_FORMAT = SimpleDateFormat. getDateTimeInstance (); private NfcAdapter mAdapter; private PendingIntent mPendingIntent; private NdefMessage success; private TextView promt; private AlertDialog mDialog; @ Overridepublic void onCreate (Bundle success) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); promt = (TextView) findViewById (R. id. promt); resolveIntent (GetIntent (); mDialog = new AlertDialog. builder (this ). setNeutralButton ("OK", null ). create (); // obtain the default NFC controller mAdapter = NfcAdapter. getdefaadapter adapter (this); // intercept system-level NFC scanning, for example, scanning Bluetooth mPendingIntent = PendingIntent. getActivity (this, 0, new Intent (this, getClass ()). addFlags (Intent. FLAG_ACTIVITY_SINGLE_TOP), 0); mNdefPushMessage = new NdefMessage (new NdefRecord [] {newTextRecord ("", Locale. ENGLISH, true)}) ;}@ Over Rideprotected void onResume () {super. onResume (); if (mAdapter = null) {if (! MAdapter. isEnabled () {showwirelesssettingsdiabled ();} showMessage (R. string. error, R. string. no_nfc); promt. setText ("the device does not support NFC! "); Return;} if (! MAdapter. isEnabled () {promt. setText ("Please enable NFC in system settings first! "); Return;} if (mAdapter! = Null) {// implicitly start mAdapter. enableForegroundDispatch (this, mPendingIntent, null, null); mAdapter. enableForegroundNdefPush (this, mNdefPushMessage) ;}@overrideprotected void onPause () {super. onPause (); if (mAdapter! = Null) {// implicitly start mAdapter. disableForegroundDispatch (this); mAdapter. disableForegroundNdefPush (this) ;}// convert the hexadecimal String to Stringprivate String hexString = "0123456789 ABCDEF"; public String decode (String bytes) {if (bytes. length ()! = 30) {return null;} ByteArrayOutputStream baos = new ByteArrayOutputStream (bytes. length ()/2); // Assemble every two hexadecimal integers into one byte for (int I = 0; I <bytes. length (); I + = 2) baos. write (hexString. indexOf (bytes. charAt (I) <4 | hexString. indexOf (bytes. charAt (I + 1); return new String (baos. toByteArray ();} // Character Sequence to hexadecimal String private static String bytesToHexString (byte [] src, boolean isPrefix) {StringBuilder stringBu Ilder = new StringBuilder (); if (isPrefix = true) {stringBuilder. append ("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. toUpperCase (Character. forDigit (src [I] >>> 4) & 0x0F, 16); buffer [1] = Character. toUpperCase (Character. forDigit (src [I] & 0x0F, 16); System. out. println (buffer); stringBuilder. append (buff Er);} return stringBuilder. toString ();} private void showMessage (int title, int message) {mDialog. setTitle (title); mDialog. setMessage (getText (message); mDialog. show ();} private NdefRecord newTextRecord (String text, Locale locale, boolean encodeInUtf8) {byte [] langBytes = locale. getLanguage (). getBytes (Charset. forName ("US-ASCII"); Charset utfEncoding = encodeInUtf8? Charset. forName ("UTF-8"): Charset. forName ("UTF-16"); byte [] textBytes = text. getBytes (utfEncoding); int utfBit = encodeInUtf8? 0: (1 <7); char status = (char) (utfBit + langBytes. length); byte [] data = new byte [1 + langBytes. length + textBytes. length]; data [0] = (byte) status; System. arraycopy (langBytes, 0, data, 1, langBytes. length); System. arraycopy (textBytes, 0, data, 1 + langBytes. length, textBytes. length); return new NdefRecord (NdefRecord. TNF_WELL_KNOWN, NdefRecord. RTD_TEXT, new byte [0], data);} private void showWirelessSe TtingsDialog () {AlertDialog. builder builder = new AlertDialog. builder (this); builder. setMessage (R. string. nfc_disabled); builder. setPositiveButton (android. r. string. OK, new DialogInterface. onClickListener () {public void onClick (DialogInterface dialogInterface, int I) {Intent intent = new Intent (Settings. ACTION_WIRELESS_SETTINGS); startActivity (intent) ;}}); builder. setNegativeButton (android. r. string. cance L, new DialogInterface. onClickListener () {public void onClick (DialogInterface dialogInterface, int I) {finish () ;}}); builder. create (). show (); return;} // preliminarily determine the type of private void resolveIntent (Intent intent) {String action = intent. getAction (); if (NfcAdapter. ACTION_TAG_DISCOVERED.equals (action) | NfcAdapter. ACTION_TECH_DISCOVERED.equals (action) | NfcAdapter. ACTION_NDEF_DISCOVERED.equals (action) {Parc Elable [] rawMsgs = intent. getParcelableArrayExtra (NfcAdapter. EXTRA_NDEF_MESSAGES); NdefMessage [] msgs; if (rawMsgs! = Null) {msgs = new NdefMessage [rawMsgs. length]; for (int I = 0; I <rawMsgs. length; I ++) {msgs [I] = (NdefMessage) rawMsgs [I] ;}} else {// Unknown tag typebyte [] empty = new byte [0]; byte [] id = intent. getByteArrayExtra (NfcAdapter. EXTRA_ID); Parcelable tag = intent. getParcelableExtra (NfcAdapter. EXTRA_TAG); byte [] payload = dumpTagData (tag ). getBytes (); NdefRecord record = new NdefRecord (NdefRecord. TNF_UNKNOWN, empty, id, payload); NdefMessage msg = new NdefMessage (new NdefRecord [] {record}); msgs = new NdefMessage [] {msg };} // Setup the viewsbuildTagViews (msgs) ;}// general public card, scanned information private String dumpTagData (Parcelable p) {StringBuilder sb = new StringBuilder (); tag tag = (Tag) p; byte [] id = tag. getId (); sb. append ("Tag ID (hex ):"). append (getHex (id )). append ("\ n"); sb. append ("Tag ID (dec ):"). append (getDec (id )). append ("\ n"); sb. append ("ID (reversed ):"). append (getReversed (id )). append ("\ n"); String prefix = "android. nfc. tech. "; sb. append ("Technologies:"); for (String tech: tag. getTechList () {sb. append (tech. substring (prefix. length (); sb. append (",");} sb. delete (sb. length ()-2, sb. length (); for (String tech: tag. getTechList () {if (tech. equals (MifareClassic. class. getName () {sb. append ('\ n'); MifareClassic mifareTag = MifareClassic. get (tag); String type = "Unknown"; switch (mifareTag. getType () {case MifareClassic. TYPE_CLASSIC: type = "Classic"; break; case MifareClassic. TYPE_PLUS: type = "Plus"; break; case MifareClassic. TYPE_PRO: type = "Pro"; break;} sb. append ("Mifare Classic type:"); sb. append (type); sb. append ('\ n'); sb. append ("Mifare size:"); sb. append (mifareTag. getSize () + "bytes"); sb. append ('\ n'); sb. append ("Mifare sectors:"); sb. append (mifareTag. getSectorCount (); sb. append ('\ n'); sb. append ("Mifare blocks:"); sb. append (mifareTag. getBlockCount ();} if (tech. equals (MifareUltralight. class. getName () {sb. append ('\ n'); MifareUltralight mifareUlTag = MifareUltralight. get (tag); String type = "Unknown"; switch (mifareUlTag. getType () {case MifareUltralight. TYPE_ULTRALIGHT: type = "Ultralight"; break; case MifareUltralight. TYPE_ULTRALIGHT_C: type = "Ultralight C"; break;} sb. append ("Mifare Ultralight type:"); sb. append (type) ;}} return sb. toString ();} private String getHex (byte [] bytes) {StringBuilder sb = new StringBuilder (); for (int I = bytes. length-1; I> = 0; -- I) {int B = bytes [I] & 0xff; if (B <0x10) sb. append ('0'); sb. append (Integer. toHexString (B); if (I> 0) {sb. append ("") ;}} return sb. toString ();} private long getDec (byte [] bytes) {long result = 0; long factor = 1; for (int I = 0; I <bytes. length; ++ I) {long value = bytes [I] & 0 xffl; result + = value * factor; factor * = 256l;} return result ;} private long getReversed (byte [] bytes) {long result = 0; long factor = 1; for (int I = bytes. length-1; I> = 0; -- I) {long value = bytes [I] & 0 xffl; result + = value * factor; factor * = 256l ;} return result;} // display NFC scanned data private void buildTagViews (NdefMessage [] msgs) {if (msgs = null | msgs. length = 0) {return;} // Parse the first message in the list // Build views for all of the sub recordsDate now = new Date (); List
Records = NdefMessageParser. parse (msgs [0]); final int size = records. size (); for (int I = 0; I <size; I ++) {TextView timeView = new TextView (this); timeView. setText (TIME_FORMAT.format (now); ParsedNdefRecord record = records. get (I); promt. append (record. getViewText () ;}}// obtain @ Overridepublic void onNewIntent (Intent intent) {setIntent (intent); resolveIntent (intent );}}
2. androidManifest Configuration