Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NFC sur Android 2.3

NFC sur Android 2.3

Présentation de l'api NFC sur Android 2.3

Olivier Gonthier

September 23, 2011
Tweet

More Decks by Olivier Gonthier

Other Decks in Programming

Transcript

  1. PA U G S EP T EM B R E

    2011 Présentation du NFC
  2. Présentation • Olivier GONTHIER o Etudiant 5A à l'ESIEA o

    Développeur chez SMS-BACKING o Portfolio : r0ly.fr o Twitter : @rolios A la recherche d'un stage de fin d'études…
  3. Plan • Etat de l’art • NFC sur Android 1)

    Présentation API 2) Permissions requises 3) "Foreground dispatch system" 4) "Intent dispatch system"  NDEF discovered  Tech discovered  Tag discovered 5) Data  Lecture  Ecriture  Peer to peer • Conclusion
  4. Etat de l'art • Sur Android, une dizaine d'appareils (Nexus

    S, Galaxy S II, Xperia Acro, Lg LU6200, Acer Liquid express, Sony Nozomi, Nexus Prime, LG Gelato nfc, ...) • Les prochains blackberry • Iphone 5 ? • Nokia N9 sous meego • Nokia-6131 ( le premier téléphone nfc) , nokia C7 • Windows phone 7: peu probable pour le moment
  5. L E N F C S U R A N

    DR OI D 1 - Présentation API
  6. Présentation API • Introduit avec Android 2.3 et le Nexus

    S • Première API nfc avec Android 2.3 (API 9, Décembre 2010)  Très limitée • API complète avec Android 2.3.3 (API 10, Février 2011) • Fournit des outils pour détecter les Tags, lire ou écrire le contenu de ces tags, et communiquer avec d'autres puces NFC
  7. L E N F C S U R A N

    DR OI D 2 - Permissions requises
  8. Permissions requises • Pour utiliser le nfc: <uses-permission android:name="android.permission.NFC" />

    • Pour n'apparaître sur l'android market que pour les devices ayant une puce nfc: <uses-feature android:name="android.hardware.nfc" android:required="true" /> • Pour définir le niveau d'api nécessaire: <uses-sdk android:minSdkVersion="10"/>
  9. L E N F C S UR A N D

    R OI D 3 - Foreground dispatch system
  10. Foreground dispatch system Permet de déclarer l’application active comme prioritaire

    pour le traitement des tags pi = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTI VITY_SINGLE_TOP) , 0); ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try{ ndef.addDataType("text/plain"); }catch (MalformedMimeTypeException e) { Log.e("NfcForecast", e.getMessage()); } intentFiltersArray = new IntentFilter[] {ndef}; techList = new String[][]{new String[] {NfcA.class.getName() }};
  11. Foreground dispatch system @Override protected void onResume() { super.onResume(); adapter.enableForegroundDispatch(this,

    pi, intentFiltersArray, techList); } @Override protected void onPause() { super.onPause(); adapter.disableForegroundDispatch(this); //ne pas oublier de désactiver quand l’application est suspendue } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); //Reaction }
  12. L E N F C S UR A N D

    R OI D 4 - Intent dispatch system
  13. L E N F C S U R A N

    D R O I D 4 - I N T E N T D I S PAT C H S Y S T E M Ndef discovered
  14. NdefDiscovered • Pour du texte, ou autre type mime :

    <intent-filter > <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <data android:mimeType="text/plain"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> • Pour une URL : <intent-filter > <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <data android:scheme="http" android:host="www.r0ly.fr"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>
  15. L E N F C S UR A N D

    R OI D 4 - I N T E N T D I SPAT C H SY ST E M Tech discovered
  16. Présentation des technologies TagTechnology The interface that all tag technology

    classes must implement. NfcA Provides access to NFC-A (ISO 14443-3A) properties and I/O operations. NfcB Provides access to NFC-B (ISO 14443-3B) properties and I/O operations. NfcF Provides access to NFC-F (JIS 6319-4) properties and I/O operations. NfcV Provides access to NFC-V (ISO 15693) properties and I/O operations. IsoDep Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations. Ndef Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF. NdefFormatable Provides a format operations for tags that may be NDEF formattable. MifareClassic Provides access to MIFARE Classic properties and I/O operations, if this Android device supports MIFARE. MifareUltralight Provides access to MIFARE Ultralight properties and I/O operations, if this Android device supports MIFARE.
  17. Tech discovered • Dans le manifest: <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter>

    <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/techlist"/> • Dans un fichier xml/techlist.xml: <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.MifareClassic</tech> </tech-list> </resources>
  18. L E N F C S UR A N D

    R OI D 4 - I N T E N T D I SPAT C H SY ST E M Tag discovered
  19. L E N F C S UR A N D

    R OI D 5 - Data
  20. Récupérer la référence du tag • Si on utilise le

    dispatch system: @Override protected void onResume() { super.onResume(); Intent i = this.getIntent(); if(i.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) Tag tagFromIntent = i.getParcelableExtra(NfcAdapter.EXTRA_TAG); } • Si on utilise le foreground system: @Override protected void onNewIntent(Intent i) { super.onNewIntent(intent); if(i.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) Tag tagFromIntent = i.getParcelableExtra(NfcAdapter.EXTRA_TAG); }
  21. L E N F C S UR A N D

    R OI D 5 - D ATA Lecture
  22. Récupérer les NdefMessage Les tags contiennent un ensemble de NdefMessage

    qui contiennent les données. public NdefMessage[] getNdefMessages(Intent intent){ NdefMessage[] messages=null; Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMsgs != null) { messages = new NdefMessage[rawMsgs.length]; for (int i = 0; i < rawMsgs.length; i++) { messages[i] = (NdefMessage) rawMsgs[i]; } } else { // Type du tag inconnu byte[] empty = new byte[] {}; NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty); NdefMessage msg = new NdefMessage(new NdefRecord[] {record}); messages = new NdefMessage[] {msg}; } return messages; }
  23. NdefRecord Chaque NdefMessage contient un ensemble de NdefRecord. Chaque NdefRecord

    est composé de : _ un id : byte[] id = record.getId(); _ un TypeNameFormat : short tnf = record.getTnf(); _ un type: byte[] type = record.getType(); _ un payload = byte[] payload = record.getPayload(); Problème: Il faut "décoder" les informations.
  24. Récupérer les NdefRecords public NdefRecord[][] getNdefRecords(NdefMessage[] msgs) { NdefRecord[][] records=null;

    if(msgs!=null){ records = new NdefRecord[msgs.length][]; for(int i=0; i<msgs.length; i++){ records[i]= new NdefRecord[msgs[i].getRecords().length]; records[i]= msgs[i].getRecords(); } } return records; }
  25. Décodage, byte[ ] to String new String(byte[]) est déconseillé, car

    l'encodage peut varier. Une solution : String getTextData(byte[] payload) { try { String texteCode = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16"; int langageCodeTaille = payload[0] & 0077; return new String(payload, langageCodeTaille + 1, payload.length - langageCodeTaille - 1, texteCode); } catch(UnsupportedEncodingException e){ Log.e("NfcReaderActivity", e.getMessage()); return null; } }
  26. L E N F C S UR A N D

    R OI D 5 - D ATA Ecriture
  27. Instancier un NdefRecord NdefRecord createRecord(String message) { byte[] langBytes =

    Locale.ENGLISH.getLanguage().getBytes(Charset.forName("US-ASCII")); byte[] textBytes = message.getBytes(Charset.forName("UTF-8")); char status = (char) (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); }
  28. Ecrire le tag Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); try{ NdefRecord[] records

    = {createRecord("Test Message")}; NdefMessage message = new NdefMessage(records); Ndef ndef = Ndef.get(tag); ndef.connect(); ndef.writeNdefMessage(message); ndef.close(); }(...)
  29. L E N F C S UR A N D

    R OI D 5 - D ATA Peer to peer
  30. Peer to peer Moyen de communication intéressant : envoie continuellement

    des NdefMessage. public void onResume() { super.onResume(); if (mAdapter != null) mAdapter.enableForegroundNdefPush(this,myNdefMessage); } public void onPause() { super.onPause(); if (mAdapter != null) mAdapter.disableForegroundNdefPush(this); }
  31. Conclusion Points importants à retenir : • Etre le plus

    précis possible pour la récupération des tags : définir la technologie attendue ainsi que son contenu • Pour la lecture, faire attention au décodage • Pour l’écriture, bien construire son NdefRecord