Android NFC and androidnfc
NFC introduction:
Near Field Communication Near-Field Communication is a data transmission technology.
A major difference from wifi, Bluetooth, infrared and other data transmission technologies is that the effective distance generally cannot exceed 4 cm.
NFC supports three working modes:
1. card reader mode;
2. Simulation card mode;
3. Point-to-point mode;
1. card reader mode:
Use NFC devices (Android phones supporting NFC) to read information from tags, stickers, newspapers, postcards, and other media containing NFC chips, or write data to these media.
2. Simulation card mode:
The basic principle is to use NFC-supported mobile phones or other electronic devices as debit cards, credit cards, bus cards, access cards, and other IC cards) encapsulated into data packets stored in mobile phones supporting NFC, an NFC frequency converter (equivalent to the card reader used for traditional IC cards) is also required during use, and the mobile phone is close to the NFC frequency converter, the mobile phone will receive a signal sent from the NFC frequency generator. After a series of complex verification, the information of the IC card will be transmitted to the NFC frequency generator. Finally, the IC card data will be transmitted to the computer connected to the NFC frequency generator, and perform corresponding operations (such as electronic transfers and door opening ).
3. Point-to-Point Mode:
Similar to Bluetooth and infrared, it can be used for data exchange between different NFC devices, but the valid distance between NFC point-to-point mode is shorter and cannot exceed 4 cm; however, if both devices use Android4.2 and later versions, NFC will directly use Bluetooth for transmission. This technology is called Android Beam, therefore, the Android Beam data transmission devices are not limited to 4cm.
Basic knowledge:
1. the Android sdk api mainly supports the NFC Forum Standard (Forum Standard). This Standard is called NDEF (NFC Data Exchange Format, NFC Data Exchange Format );
2. the Android sdk api supports the following three NDEF data operations:
A. Read data in NDEF format from NFC tags;
B. Write Data in NDEF format to NFC tags;
C. Use Android Beam technology to send NDEF data to another NFC device;
3. an NFC connection will be established within 0.1 seconds before one NFC device reads data from an NFC tag or another NFC device, and the data will automatically flow from the read end to the read end; the data receiving end calls the corresponding Activity (also known as Tag Dispatch) based on the specific data format and Tag type. All these activities need to define the Intent Filter, these Intent filters specify different filtering mechanisms, which are divided into three levels, also known as the NFC triple filtering mechanism.
4. NDEF_DISCOVERED:
Filter only NDEF data in a fixed format. For example: plain text, specified protocol (http, ftp, smb, etc.) URI;
TECH_DISCOVERED:
When the filtering mechanism specified by ACTION_NDEF_DISCOVERED cannot match tags, this filtering mechanism is used for matching. This filtering mechanism does not match tags in the data format, it matches the data storage formats supported by tags. Therefore, this filtering mechanism has a wider range;
TAG_DISCOVERED:
If the NFC filter mechanism is regarded as if... else if... if the else statement is used, this filtering mechanism is equivalent to the else part. If the current two filters fail to match, the system will use this filter to process them, this filtering mechanism is used to process unrecognized tags (the data format is incorrect and the formats supported by tags do not match ).
5. the Android system matches NDEF_DISCOVERED, TECH_DISCOVERED, and TAG_DISCOVERED in sequence. If tags still cannot be matched through the triple filter mechanism, nothing is done. Generally, after a Tag is successfully matched, the Android device will make a sound that is crisp, And the Tag is not successfully matched, it will make a dull sound.
The process is as follows:
6. In the manifest file, you need to set the following parts:
Set permissions:
<Uses-permission android: name = "android. permission. NFC"/>
Android version restrictions:
Android: minSdkVersion = "14"
Restrict the devices to be installed:
<Uses-feature android: name = "android. hardware. nfc" android: required = "true"/>
Set the Intent Filter of the Activity, for example, one of the three filtering mechanisms:
<Intent-filter>
<Action android: name = "android. nfc. action. TECH_DISCOVERED"/>
</Intent-filter>
Next, let's take the first example. This example belongsCard reader modeRead and Write Data from the NFC chip.
The content of its manifest file is as follows:
<? Xml version = "1.0" encoding = "UTF-8"?> <Manifest xmlns: android = "http://schemas.android.com/apk/res/android" package = "com. r8c. nfc_demo "android: versionCode =" 110 "android: versionName =" 1.1.0 "> <uses-sdk android: minSdkVersion =" 15 "android: targetSdkVersion =" 17 "/> <! -- NFC permission statement --> <uses-permission android: name = "android. permission. NFC "/> <uses-feature android: name =" android. hardware. nfc "android: required =" true "/> <application android: allowBackup =" true "android: icon =" @ drawable/ic_launcher "android: label = "@ string/app_name" android: theme = "@ style/AppTheme"> <activity android: name = "com. r8c. nfc_demo.NfcDemoActivity "android: configChanges =" orientation | keyboardHidden | ScreenSize "android: label =" @ string/app_name "android: launchMode =" singleTask "> <intent-filter> <action android: name =" android. intent. action. MAIN "/> <category android: name =" android. intent. category. LAUNCHER "/> </intent-filter> <! -- TECH_DISCOVERED nfc --> <intent-filter> <action android: name = "android. nfc. action. TECH_DISCOVERED"/> </intent-filter> <! -- Then set the resource to call the files in the created folder xml --> <meta-data android: name = "android. nfc. action. TECH_DISCOVERED "android: resource =" @ xml/nfc_tech_filter "/> </activity> </application> </manifest>
The content of its Activity is as follows, including reading, writing, and deleting: (the delete function is implemented by writing null values)
Import java. io. IOException; import java. io. unsupportedEncodingException; import java. nio. charset. charset; import android. media. audioManager; import android. media. mediaPlayer; import android. media. ringtoneManager; import android.net. uri; import android. nfc. formatException; import android. nfc. ndefMessage; import android. nfc. ndefRecord; import android. nfc. nfcAdapter; import android. nfc. tag; import android. nfc. tec H. mifareUltralight; import android. nfc. tech. ndef; import android. nfc. tech. nfcA; import android. OS. bundle; import android. app. activity; import android. app. pendingIntent; import android. content. context; import android. content. intent; import android. content. intentFilter; import android. graphics. color; import android. util. log; import android. view. menu; import android. view. view; import android. view. view. onClickList Ener; import android. widget. button; import android. widget. textView; import android. widget. toast; public class NfcDemoActivity extends Activity implements OnClickListener {// NFC adapter private NfcAdapter nfcAdapter = null; // convey intent private PendingIntent pi = null; // filter out Intentprivate IntentFilter tagDetected = null; // text control private TextView promt = null; // whether the NFC function label private boolean isNFC_support = fal is supported Se; // read, write, and delete Button controls private Button readBtn, writeBtn, deleteBtn; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_nfc_demo); setupViews (); initNFCData () ;}@ Overrideprotected void onResume () {super. onResume (); if (isNFC_support = false) {// if the device does not support NFC or the NFC function is not enabled, return the return ;} // start listening to whether the NFC device is connected to startNFC_Listener (); if (NfcAdapter. A CTION_TECH_DISCOVERED.equals (this. getIntent (). getAction () {// note that the code in this if object will hardly come in, because the listening NFC connection is enabled in the previous line of code, and the next line of code will immediately receive the intent of the NFC connection, this probability is very small // process this intentprocessIntent (this. getIntent () ;}}@ Overrideprotected void onPause () {super. onPause (); if (isNFC_support = true) {// if the current Activity is not at the front of the mobile phone, stop listening to the NFC device connection stopNFC_Listener ();}} @ Overrideprotected void onNewIntent (Intent intent) {super. onNewIntent (intent); // current ap P is running on the front-end interface. When intent is sent, the system will call the onNewIntent callback method, send intent. // you only need to check whether the intent is an NFC-related intent here. if yes, call the processing method if (NfcAdapter. ACTION_TECH_DISCOVERED.equals (intent. getAction () {processIntent (intent) ;}@overridepublic void onClick (View v) {// click the read button and then if (v. getId () = R. id. read_btn) {try {String content = read (tagFromIntent); if (content! = Null &&! Content. equals ("") {promt. setText (promt. getText () + "nfc TAG content: \ n" + content + "\ n");} else {promt. setText (promt. getText () + "nfc TAG content: \ n" + "content blank \ n");} catch (IOException e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "nfc read exception", e);} catch (FormatException e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "nfc read exception", e);} // click Write to} else if (v. getId () = R. id. write_btn) {try {write (tagFromIntent);} catch (IOException e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "nfc writing exception", e);} catch (FormatException e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "nfc writing exception", e) ;}} else if (v. getId () = R. id. delete_btn) {try {delete (tagFromIntent);} catch (IOExce Ption e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "deleting nfc exceptions", e);} catch (FormatException e) {promt. setText (promt. getText () + "error:" + e. getMessage () + "\ n"); Log. e ("myonclick", "nfc deletion exception", e) ;}} private void setupViews () {// control binding promt = (TextView) findViewById (R. id. promt); readBtn = (Button) findViewById (R. id. read_btn); writeBtn = (Button) findViewById (R. id. wr Ite_btn); deleteBtn = (Button) findViewById (R. id. delete_btn); // assign the initial text promt to the text control. setText ("waiting for RFID tags"); // monitors the readBtn controls for reading, writing, and deleting buttons. setOnClickListener (this); writeBtn. setOnClickListener (this); deleteBtn. setOnClickListener (this);} private void initNFCData () {// The initialization device supports the NFC function isNFC_support = true; // obtain the default nfc adapter nfcAdapter = NfcAdapter. getdefaadapter adapter (getApplicationContext (); // The message defines String metaInfo = ""; // determines whether the device is Supports NFC or starts NFCif (nfcAdapter = null) {metaInfo = "the device does not support NFC! "; Toast. makeText (this, metaInfo, Toast. LENGTH_SHORT). show (); isNFC_support = false;} if (! NfcAdapter. isEnabled () {metaInfo = "Please enable NFC in system settings first! "; Toast. makeText (this, metaInfo, Toast. LENGTH_SHORT ). show (); isNFC_support = false;} if (isNFC_support = true) {init_NFC ();} else {promt. setTextColor (Color. RED); promt. setText (metaInfo) ;}@overridepublic boolean onCreateOptionsMenu (Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater (). inflate (R. menu. nfc_demo, menu); return true;} // convert the Character Sequence to a hexadecimal string private String bytesToHexString (byte [] src) {return bytesToHexString (src, true);} private String bytesToHexString (byte [] src, boolean isPrefix) {StringBuilder stringBuilder = 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. for Digit (src [I] >>> 4) & 0x0F, 16); buffer [1] = Character. toUpperCase (Character. forDigit (src [I] & 0x0F, 16); System. out. println (buffer); stringBuilder. append (buffer);} return stringBuilder. toString ();} private Tag tagFromIntent;/*** Parses the NDEF Message from the intent and prints to the TextView */public void processIntent (Intent intent) {if (isNFC_support = false) return; // retrieves the TAGtagFromI encapsulated in the intent. Ntent = intent. getParcelableExtra (NfcAdapter. EXTRA_TAG); promt. setTextColor (Color. BLUE); String metaInfo = ""; metaInfo + = "card ID:" + bytesToHexString (tagFromIntent. getId () + "\ n"; Toast. makeText (this, "Find card", Toast. LENGTH_SHORT ). show (); // Tech ListString prefix = "android. nfc. tech. "; String [] techList = tagFromIntent. getTechList (); // analyze the NFC card type: Mifare Classic/UltraLight InfoString CardType = ""; for (in T I = 0; I <techList. length; I ++) {if (techList [I]. equals (NfcA. class. getName () {// read TAGNfcA mfc = NfcA. get (tagFromIntent); try {if ("". equals (CardType) CardType = "MifareClassic card type \ n does not support NDEF message \ n";} catch (Exception e) {e. printStackTrace () ;}} else if (techList [I]. equals (MifareUltralight. class. getName () {MifareUltralight mifareUlTag = MifareUltralight. get (tagFromIntent); String lightType = ""; // Type Infoswitch (mifareUlTag. getType () {case MifareUltralight. TYPE_ULTRALIGHT: lightType = "Ultralight"; break; case MifareUltralight. TYPE_ULTRALIGHT_C: lightType = "Ultralight C"; break;} CardType = lightType + "card type \ n"; Ndef ndef = Ndef. get (tagFromIntent); CardType + = "maximum data size:" + ndef. getMaxSize () + "\ n" ;}} metaInfo + = CardType; promt. setText (metaInfo);} // read method private String read (Tag tag) throws IOEx Ception, FormatException {if (tag! = Null) {// parse the Tag to obtain NDEF instance Ndef ndef = Ndef. get (tag); // open the connection ndef. connect (); // get NDEF message NdefMessage message = ndef. getNdefMessage (); // converts a message to a byte array byte [] data = message. toByteArray (); // converts a byte array to a String str = new String (data, Charset. forName ("UTF-8"); // close the ndef connection. close (); return str;} else {Toast. makeText (NfcDemoActivity. this, "the device is disconnected from the nfc card. Please try again... ", Toast. LENGTH_SHORT ). show ();} return null;} // write method private void Write (Tag tag) throws IOException, FormatException {if (tag! = Null) {// create an NdefRecord array. In this example, the array has only one element NdefRecord [] records = {createRecord ()}; // create an NdefMessage instance NdefMessage message = new NdefMessage (records); // parse the TAG to obtain the NDEF instance Ndef ndef = Ndef. get (tag); // open the connection ndef. connect (); // write NDEF information ndef. writeNdefMessage (message); // closes the ndef connection. close (); promt. setText (promt. getText () + "data written successfully! "+" \ N ");} else {Toast. makeText (NfcDemoActivity. this, "the device is disconnected from the nfc card. Please try again... ", Toast. LENGTH_SHORT ). show () ;}// deletion method private void delete (Tag tag) throws IOException, FormatException {if (tag! = Null) {// create an NdefRecord instance NdefRecord nullNdefRecord = new NdefRecord (NdefRecord. TNF_MIME_MEDIA, new byte [] {}, new byte [] {}, new byte [] {}); NdefRecord [] records = {nullNdefRecord }; ndefMessage message = new NdefMessage (records); // parse the TAG to obtain NDEF instance Ndef ndef = Ndef. get (tag); // open the connection ndef. connect (); // write information ndef. writeNdefMessage (message); // closes the ndef connection. close (); promt. setText (promt. getText () + "data deleted! "+" \ N ");} else {Toast. makeText (NfcDemoActivity. this, "the device is disconnected from the nfc card. Please try again... ", Toast. LENGTH_SHORT ). show () ;}/// return an NdefRecord instance private NdefRecord createRecord () throws UnsupportedEncodingException {// assemble the String and prepare the information you want to write. String msg = "BEGIN: VCARD \ n "+" VERSION: 2.1 \ n "+" Hubei Province, China \ n "+" School of Computer Science, Wuhan University \ n "+" END: VCARD "; // convert the string to a byte array byte [] textBytes = msg. getBytes (); // encapsulate the byte array into an NdefRecord instance to remove NdefRecord textRecord = New NdefRecord (NdefRecord. TNF_MIME_MEDIA, "text/x-vCard ". getBytes (), new byte [] {}, textBytes); return textRecord;} private MediaPlayer ring () throws Exception, IOException {// TODO Auto-generated method stubUri alert = RingtoneManager. getDefaultUri (RingtoneManager. TYPE_NOTIFICATION); MediaPlayer player = new MediaPlayer (); player. setDataSource (this, alert); final AudioManager audioManager = (AudioMana Ger) getSystemService (Context. AUDIO_SERVICE); if (audioManager. getStreamVolume (AudioManager. STREAM_NOTIFICATION )! = 0) {player. setAudioStreamType (AudioManager. STREAM_NOTIFICATION); player. setLooping (false); player. prepare (); player. start ();} return player;} private void startNFC_Listener () {// start to monitor whether the NFC device is connected. If the connection is established, the pi intends to nfcAdapter. enableForegroundDispatch (this, pi, new IntentFilter [] {tagDetected}, null);} private void stopNFC_Listener () {// stop listening to whether the NFC device is connected to nfcAdapter. disableForegroundDispatch (this);} private void init_NFC () {// initialize PendingIntent. When an NFC device is connected, it is handed over to the current Activity for processing pi = PendingIntent. getActivity (this, 0, new Intent (this, getClass ()). addFlags (Intent. FLAG_ACTIVITY_SINGLE_TOP), 0); // creates an IntentFilter. The second filtering mechanism tagDetected = new IntentFilter (NfcAdapter. ACTION_TECH_DISCOVERED); tagDetected. addCategory (Intent. CATEGORY_DEFAULT );}}
The complete source code download link for this example is as follows:
Android NFC Demo1