Esti curios de ce este NFC si cum poate fi integrat in propriile aplicatii Android? Acest tutorial vă va prezenta rapid subiectul înainte de a vă scufunda și de a vă învăța cum să construiți o aplicație simplă pentru cititoarele NFC!
NFC este abrevierea pentru Near Field Communication. Este standardul internațional pentru schimbul de date fără contacte. Spre deosebire de o gamă largă de alte tehnologii, cum ar fi LAN fără fir și Bluetooth, distanța maximă a două dispozitive este de 10 cm. Dezvoltarea standardului a început în 2002 de către NXP Semiconductors și Sony. Forumul NFC, un consorțiu format din peste 170 de companii și membri, printre care Mastercard, NXP, Nokia, Samsung, Intel și Google, a elaborat noi specificații începând din 2004.
Există diferite posibilități de utilizare a dispozitivelor NFC cu dispozitive mobile; de exemplu, bilete fără hârtie, controale de acces, plăți fără numerar și chei de la mașină. Cu ajutorul etichetelor NFC puteți controla telefonul și puteți schimba setările. Datele pot fi schimbate pur și simplu prin menținerea a două dispozitive una lângă cealaltă.
În acest tutorial vreau să vă explic cum să implementați NFC cu Android SDK, care sunt capcanele și ce trebuie să aveți în vedere. Vom crea o aplicație pas cu pas, care poate citi conținutul etichetelor NFC care suportă NDEF.
Există o varietate de etichete NFC care pot fi citite cu un smartphone. Spectrul variază de la autocolante simple și inele cheie până la carduri complexe cu hardware criptografic integrat. Etichetele diferă de asemenea în tehnologia lor cu chip. Cel mai important este NDEF, care este susținut de majoritatea etichetelor. În plus, Mifare ar trebui menționat, deoarece este tehnologia cea mai utilizată a cipurilor contactless din întreaga lume. Unele etichete pot fi citite și scrise, în timp ce altele sunt citite sau criptate.
Numai formatul de schimb de date NFC (NFC) este discutat în acest tutorial.
Începem cu un nou proiect și o activitate necompletată. Este important să selectați o versiune SDK minimă de nivel 10, deoarece NFC este acceptată numai după Android 2.3.3. Nu uitați să alegeți propriul nume al pachetului. am ales net.vrallev.android.nfc.demo, deoarece vrallev.net este domeniul site-ului meu web, iar cealaltă parte se referă la subiectul acestei aplicații.
Aspectul implicit generat de Eclipse este aproape suficient pentru noi. Am adăugat doar un ID la TextView și am modificat textul.
Pentru a avea acces la hardware-ul NFC, trebuie să solicitați permisiunea în manifest. Dacă aplicația nu va funcționa fără NFC, puteți specifica această condiție cu eticheta funcțiilor-utilizare. Dacă este necesar NFC, aplicația nu poate fi instalată pe dispozitive fără ea și Google Play va afișa aplicația numai utilizatorilor care dețin un dispozitiv NFC.
MainActivitatea trebuie să fie formată numai din metoda onCreate (). Puteți interacționa cu hardware-ul prin clasa NfcAdapter. Este important să aflați dacă NfcAdapter este nul. În acest caz, dispozitivul Android nu acceptă NFC.
pachet net.vrallev.android.nfc.demo; importă android.app.Activity; import șiroid.nfc.NfcAdapter; import android.os.Bundle; import șiroid.widget.TextView; importă android.widget.Toast; / ** * Activitate pentru citirea datelor dintr-o etichetă NDEF. * * @author Ralf Wondratschek * * / clasa publica MainActivity extinde Activitatea public static final String TAG = "NfcDemo"; private TextView mTextView; privat NfcAdapter mNfcAdapter; @Override protejate void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mTextView = (TextView) findViewById (R.id.textView_explanare); mNfcAdapter = NfcAdapter.getDefaultAdapter (acest lucru); dacă (mNfcAdapter == null) // Stop aici, avem nevoie de NFC Toast.makeText (acest lucru, "Acest aparat nu suportă NFC", Toast.LENGTH_LONG) .show (); finalizarea(); întoarcere; dacă (! mNfcAdapter.isEnabled ()) mTextView.setText ("NFC este dezactivat"); altceva mTextView.setText (R.string.explanation); handleIntent (getIntent ()); void private handleIntent (Intent intent) // TODO: manipulați Intent
Dacă începem acum aplicația noastră, putem vedea textul dacă NFC este activat sau dezactivat.
Avem aplicația noastră de probă și doriți să primiți o notificare de la sistem când atașăm o etichetă NFC pe dispozitiv. Ca de obicei, Android utilizează sistemul Intent pentru a livra etichete în aplicații. Dacă mai multe aplicații pot gestiona intenția, se va afișa selectorul de activități și utilizatorul poate decide ce aplicație va fi deschisă. Adresele URL de deschidere sau informațiile de partajare sunt tratate în același mod.
Există trei filtre diferite pentru etichete:
Lista este sortată de la cea mai înaltă la cea mai mică prioritate.
Ce se întâmplă atunci când o etichetă este atașată la telefonul smartphone? Dacă sistemul detectează o etichetă cu suport NDEF, se declanșează un Intent. Un ACTION_TECH_DISCOVERED Intenția este declanșată dacă nu este înregistrată nicio activitate din nicio aplicație pentru intenția NDEF sau dacă eticheta nu acceptă NDEF. Dacă din nou nu se găsește nicio aplicație pentru Intent sau tehnologia chip nu a putut fi detectată, atunci a ACTION_TAG_DISCOVERED Intenția este declanșată. Următorul grafic prezintă procesul:
În concluzie, aceasta înseamnă că fiecare aplicație trebuie să se filtreze după intenția cu cea mai mare prioritate. În cazul nostru, acesta este intenția NDEF. Punem în aplicare ACTION_TECH_DISCOVERED În primul rând intenția de a evidenția diferența dintre priorități.
Trebuie să specificăm tehnologia care ne interesează. În acest scop, vom crea un subfolder numit xml în res pliant. În acest dosar vom crea fișierul nfc_tech_filter.xml, în care specificăm tehnologiile.
android.nfc.tech.Ndef
Acum trebuie să creați un IntentFilter în manifeste și aplicația va fi pornită când atașăm o etichetă.
Dacă nu este înregistrată nicio altă aplicație pentru această intenție, activitatea noastră va începe imediat. Pe dispozitivul meu, cu toate acestea, alte aplicații sunt instalate, astfel încât selectorul de activitate este afișat.
După cum am menționat anterior, intenția descoperită de Tech are a doua prioritate cea mai mare. Cu toate acestea, deoarece aplicația noastră va sprijini numai NDEF, putem folosi în schimb NDEF Discovered Intent, care are o prioritate mai mare. Putem șterge din nou lista de tehnologii și vom înlocui IntentFilter cu următorul.
Când atașăm eticheta acum, aplicația va fi pornită ca mai înainte. Există totuși o diferență pentru mine. Selectorul de activități nu apare și aplicația începe imediat, deoarece intenția NDEF are o prioritate mai mare, iar celelalte aplicații sunt înregistrate doar pentru prioritățile inferioare. Asta e exact ceea ce vrem.
Rețineți că rămâne o problemă. Când aplicația noastră este deja deschisă și am atașat din nou eticheta, aplicația este deschisă a doua oară, în loc să transmită eticheta direct. Acesta nu este comportamentul nostru. Aveți posibilitatea să ocoliți problema utilizând o expediere în prim plan.
În locul sistemului care a distribuit intenția, vă puteți înregistra activitatea pentru a primi eticheta direct. Acest lucru este important pentru un anumit flux de lucru, unde nu are sens să deschideți o altă aplicație.
Am inserat explicațiile în locurile potrivite din cod.
pachet net.vrallev.android.nfc.demo; importă android.app.Activity; import șiroid.app.PendingIntent; import șiroid.content.Intent; import android.content.IntentFilter; import șiroid.content.IntentFilter.MalformedMimeTypeException; import șiroid.nfc.NfcAdapter; import android.os.Bundle; import șiroid.widget.TextView; importă android.widget.Toast; / ** * Activitate pentru citirea datelor dintr-o etichetă NDEF. * * @author Ralf Wondratschek * * / clasa publica MainActivity extinde Activitatea public static final String MIME_TEXT_PLAIN = "text / simplu"; public static final TAG = "NfcDemo"; private TextView mTextView; privat NfcAdapter mNfcAdapter; @Override protejate void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mTextView = (TextView) findViewById (R.id.textView_explanare); mNfcAdapter = NfcAdapter.getDefaultAdapter (acest lucru); dacă (mNfcAdapter == null) // Stop aici, avem nevoie de NFC Toast.makeText (acest lucru, "Acest aparat nu suportă NFC", Toast.LENGTH_LONG) .show (); finalizarea(); întoarcere; dacă (! mNfcAdapter.isEnabled ()) mTextView.setText ("NFC este dezactivat"); altceva mTextView.setText (R.string.explanation); handleIntent (getIntent ()); @Override protejate void onResume () super.onResume (); / ** * Este important ca activitatea să fie în prim plan (reluată). În caz contrar * este aruncat o excepție ilegală. * / setupForegroundDispatch (acest lucru, mNfcAdapter); @Override protejate void onPause () / ** * Apelați acest lucru înainte dePause, în caz contrar este aruncat și un IllegalArgumentException. * / stopForegroundDispatch (acest lucru, mNfcAdapter); super.onPause (); @Override protejat void onNewIntent (intent intent) / ** * Această metodă este chemată atunci când un nou Intent devine asociat cu instanța de activitate curentă. * În loc să creați o nouă activitate, se va apela onNewIntent. Pentru mai multe informații, consultați * documentația. * * În cazul nostru, această metodă este apelată atunci când utilizatorul atașează o etichetă pe dispozitiv. * / handleIntent (intenție); privid void handleIntent (intent intent) // TODO: handle Intent / ** * @param activity @ Link Activity care solicită expedierea în prim plan. * @param adapter @link NfcAdapter folosit pentru expedierea în prim plan. * / public static void setupForegroundDispatch (activitatea finală a activității, adaptor NfcAdapter) final Intent intent = intenție nouă (activity.getApplicationContext (), activity.getClass ()); intent.setFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP); finală PendingIntent pendingIntent = PendingIntent.getActivity (activitate.getApplicationContext (), 0, intenție, 0); IntentFilter [] filtre = nou IntentFilter [1]; String [] [] techList = String nou [] [] ; / / Observați că acesta este același filtru ca în manifestul nostru. filtre [0] = noi IntentFilter (); Filtre [0] .addAction (NfcAdapter.ACTION_NDEF_DISCOVERED); Filtre [0] .addCategory (Intent.CATEGORY_DEFAULT); încercați filters [0] .addDataType (MIME_TEXT_PLAIN); captură (MalformedMimeTypeException e) aruncați noul RuntimeException ("Verificați tipul mime."); adapter.enableForegroundDispatch (activitate, pendingIntent, filtre, techList); / ** * @activitate Parametru @link BaseActivity care solicită oprirea expedierii în prim plan. * @param adapter @link NfcAdapter folosit pentru expedierea în prim plan. * / static public void stopForegroundDispatch (activitate finală de activitate, adaptor NfcAdapter) adapter.disableForegroundDispatch (activitate);
Acum, când atașați o etichetă și aplicația noastră este deja deschisă, se solicită OnNewIntent și nu se creează nicio activitate nouă.
Ultimul pas este citirea datelor din etichetă. Explicațiile sunt inserate din nou în locurile potrivite din cod. NdefReaderTask este o clasă interioară privată.
pachet net.vrallev.android.nfc.demo; import java.io.UnsupportedEncodingException; import java.util.Arrays; importă android.app.Activity; import șiroid.app.PendingIntent; import șiroid.content.Intent; import android.content.IntentFilter; import șiroid.content.IntentFilter.MalformedMimeTypeException; import șiroid.nfc.NdefMessage; import șiroid.nfc.NdefRecord; import șiroid.nfc.NfcAdapter; import șiroid.nfc.Tag; import șiroid.nfc.tech.Ndef; import șiroid.os.AsyncTask; import android.os.Bundle; import șiroid.util.Log; import șiroid.widget.TextView; importă android.widget.Toast; / * * ... alte părți ale codului * / void private handleIntent (Intent intent) String action = intent.getAction (); dacă (NfcAdapter.ACTION_NDEF_DISCOVERED.equals (acțiune)) String type = intent.getType (); dacă (MIME_TEXT_PLAIN.equals (type)) Tag tag = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG); noul NdefReaderTask () executa (eticheta); altceva Log.d (TAG, "Tip mime greșit:" + tip); altfel dacă (NfcAdapter.ACTION_TECH_DISCOVERED.equals (action)) // În cazul în care vom folosi în continuare eticheta Tech Discovered Tag Intent = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG); Șir [] techList = tag.getTechList (); String căutatTech = Ndef.class.getName (); pentru (String tech: techList) if (căutatTech.equals (tech)) new NdefReaderTask () execute (tag); pauză;
/ ** * Sarcina de bază pentru citirea datelor. Nu blocați firul UI în timpul citirii. * * @author Ralf Wondratschek * * / clasa privată NdefReaderTask extinde AsyncTask@Override protejată String doInBackground (Tag ... params) Tag tag = params [0]; Ndef ndef = Ndef.get (etichetă); dacă (ndef == null) // NDEF nu este acceptată de această etichetă. retur nul; NdefMessage ndefMessage = ndef.getCachedNdefMessage (); NdefRecord [] înregistrări = ndefMessage.getRecords (); pentru (NdefRecord ndefRecord: înregistrări) if (ndefRecord.getTnf () == NdefRecord.TNF_WELL_KNOWN && Arrays.equals (ndefRecord.getType (), NdefRecord.RTD_TEXT)) încercați retur readText (ndefRecord); captură (UnsupportedEncodingException e) Log.e (TAG, "Encodare neacceptată", e); întoarce null; privat String readText (NdefRecord record) aruncă UnsupportedEncodingException / * * Vezi specificația forumului NFC pentru "Text Record Type Definition" la 3.2.1 * * http://www.nfc-forum.org/specs/ * * bit_7 definește codificarea * bit_6 rezervat pentru utilizare ulterioară, trebuie să fie 0 * bit_5 ... 0 lungimea codului limbii IANA * / byte [] payload = record.getPayload (); // Obțineți Text Encoding String textEncoding = ((sarcină utilă [0] & 128) == 0)? "UTF-8": "UTF-16"; // Obțineți codul de limbă int languageCodeLength = sarcină utilă [0] & 0063; // String languageCode = String nou (sarcină utilă, 1, limbăCodulLength, "US-ASCII"); // de exemplu. "en" // Obțineți textul retur nou String (sarcină utilă, limbăCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding); @Override protejat void onPostExecute (rezultatul șirului) if (rezultat! = Null) mTextView.setText ("Read content:" + rezultat);
Aplicația citește cu succes conținutul.
Pentru a verifica dacă datele sunt citite și scrise corect, îmi place să folosesc următoarele aplicații:
În acest tutorial v-am arătat cum pot fi extrase datele dintr-o etichetă NDEF. Ați putea extinde exemplul la alte tipuri de mime și tehnologii cu chip; o caracteristică de scriere a datelor ar fi utilă, de asemenea. Primul pas pentru a lucra cu NFC a fost făcut. Cu toate acestea, SDK-ul Android oferă mult mai multe posibilități, cum ar fi un schimb ușor de date (numit Android Beam).
Dacă doriți să vă dezvoltați în continuare dezvoltarea Android, consultați o gamă largă de șabloane utile de aplicații Android pe Envato Market. Sau închiriați un dezvoltator Android pe Envato Studio.
Ralf Wondratschek este un student în domeniul informaticii din Germania. În plus față de studiile sale, Ralf lucrează ca un freelancer în domeniul calculatoarelor mobile. În ultimii ani a lucrat cu Java, XML, HTML, JSP, JSF, Eclipse, Google App Engine și, bineînțeles, Android. El a publicat până acum două aplicații Android care pot fi găsite aici.
Puteți afla mai multe despre activitatea autorului pe pagina sa vrallev.net.
http://www.nfc-forum.org/home/n-mark.jpg
http://commons.wikimedia.org/wiki/File%3A%C3%9Cberlagert.jpg
http://developer.android.com/images/nfc_tag_dispatch.png