Tipy a triky pro NFC na Androidu

Rozhraní NFC se stává stále více populárním. Velkou zásluhu na tom mají platby pomocí NFC. Společnosti objevují výhody této technologie, která je vhodná pro přenos malých objemů dat na velmi krátkou vzdálenost, ale také pro ověření uživatele pomocí NFC, kdy další komunikace s přenosem většího množství dat probíhá přes Bluetooth.

Na svém kontě máme několik mobilních aplikací zaměřených na komunikaci přes NFC. Jedna z nich využívá toto rozhraní i pro čtení a zápis konfigurace hardwarového zařízení do paměťového čipu. Přečtěte si o problémech, se kterými jsme se v průběhu vývoje setkali. Ukážeme vám, jak jsme je vyřešili.

Všechno začíná u čipů

Čipy NDEF NFC jsou nejčastějším typem pro čtení informací pomocí NFC. Pro příklad mohou být čipy umístěny v zoologické zahradě poblíž zvířecích klecí, kdy se po přiložení telefonu k NFC čipu návštěvníkům otevře webová stránka vztahující se ke konkrétnímu místu. Velmi jednoduché. Ale jak pracovat s čipy, které podporují rozdílné technologie a účel jejich použití je o něco komplikovanější?

Pokud chcete v mobilním zařízení začít používat čip NFC, musíte mít následující řádky deklarované v souboru AndroidManifest, čímž získá vaše aplikace přístup k technologii NFC.

<manifest package="com.dactylgroup.someproject.android"
   xmlns:android="http://schemas.android.com/apk/res/android">

   <uses-permission android:name="android.permission.NFC" />
   <uses-feature android:name="android.hardware.nfc" />

   <application>
   .
   .
</manifest>

Technologie NFC jsou podle jejich priority uspořádány do tří kategorií. Nejvyšší prioritu má ACTION_NDEF_DISCOVERED, nižší ACTION_TECH_DISCOVERED a nejnižší ACTION_TAG_DISCOVEREDTyto kategorie musí být deklarovány také v souboru AndroidManifest, konkrétně v části aktivity, kde chcete skenovat čipy přes NFC. Můžete specifikovat pouze ty kategorie, které má vaše aplikace v plánu podporovat. 

Vložte zde nyní následující řádky:

<activity
   android:name="com.dactylgroup.someproject.android.controller.SomeActivity"
   android:launchMode="singleInstance"
   android:theme="@style/AppTheme ">

   <intent-filter>
  	<action android:name="android.nfc.action.NDEF_DISCOVERED" />

  	<category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
   <intent-filter>
  	<action android:name="android.nfc.action.TECH_DISCOVERED" />

  	<category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
   <intent-filter>
  	<action android:name="android.nfc.action.TAG_DISCOVERED" />

  	<category android:name="android.intent.category.DEFAULT" />
   </intent-filter>

   <meta-data
  	android:name="android.nfc.action.TECH_DISCOVERED"
  	android:resource="@xml/nfc_tech_filter" />
</activity>

Důležité jsou i soubory

Jistě jste postřehli, že se na konci předchozí ukázky nachází odkaz na resource file, o kterém jsme se zatím nezmínili. Jedná se o soubor se seznamy technologií, které bude aplikace využívat. Soubor je typu xml. Bude umístěn v resources aplikace, konkrétně ve složce s názvem xml, na který bude odkazováno také v AndroidManifestu. Ve výchozím nastavení vypadá seznam takto:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>

        <tech>android.nfc.tech.IsoDep</tech>

        <tech>android.nfc.tech.NfcA</tech>

        <tech>android.nfc.tech.NfcB</tech>

        <tech>android.nfc.tech.NfcF</tech>

        <tech>android.nfc.tech.NfcV</tech>

        <tech>android.nfc.tech.Ndef</tech>

        <tech>android.nfc.tech.NdefFormatable</tech>

        <tech>android.nfc.tech.MifareClassic</tech>

        <tech>android.nfc.tech.MifareUltralight</tech>

    </tech-list>
</resources>

Než si ho zkopírujete, přečtěte si toto! Seznam pojednává o tom, že vaše zařízení/čip NFC podporuje všechny zmíněné technologie. Pokud ne, zařízení nerozezná čip NFC jako kategorii ACTION_TECH_DISCOVERED (druhá priorita), ale jako ACTION_TAG_DISCOVERED (kategorie s nejnižší prioritou). Chcete-li podporovat technologie pro více druhů čipů, musíte definovat více tzv. tech-listů ve stejném souboru xml, například tímto způsobem:

<tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.NfcA</tech>
</tech-list>
<tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>

Na prioritě záleží

Možná přemýšlíte nad tím, koho zajímá nějaká priorita kategorií? Zajímat by měla především vás. Pokud totiž bude mít vaše aplikace poslední prioritu a jiná aplikace, například ST25 NFC Tap, může číst stejný čip s vyšší prioritou, poté systém automaticky otevře druhou aplikaci a ne vaši. Pokud obě aplikace mohou otevřít technologii se stejnou prioritou, systém Android vám nabídne dialogové okno, kde si můžete vybrat, kterou aplikací chcete požadovanou akci vykonat.

Vyhrajte si s tech-listem

Definujte co nejkonkrétnější tech-list, jak jen je to možné. Níže jsme definovali jeden pro příklad. Protože uvedený čip podporuje obě technologie, Nexus 6P jej přečte jako kategorii ACTION_TECH_DISCOVERED, ale telefony Samsung pouze jako ACTION_TAG_DISCOVERED

Objeví se nám tedy problém s prioritou zmíněný o několik řádků výše. Jelikož jsme pracovali pouze s technologií NfcV, odstranili jsme druhou technologii NdefFormatable a nyní telefon Samsung detekuje čip také jako kategorii ACTION_TECH_DISCOVERED.

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>

        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
</resources>

Pokud nevíte, kterou technologii váš NFC čip podporuje, nejjednodušší je zjistit ji pomocí aplikace ST25 NFC Tap, která vám může na jedné z jejích obrazovek ukázat podporované technologie.

Tímto jsme uzavřeli část pro detekci NFC čipu zařízením. Nyní se podíváme, jak komunikovat s čipem, tedy číst a zapisovat data.

Komunikace s čipem

Pokud deklarujete android:launchMode="singleInstance" v AndroidManifestu uvnitř tagu aktivity (aktivita, ve které chcete skenovat NFC čipy), Android nevytvoří aktivitu znovu a znovu po každém skenování čipu, ale vytvoří ji pouze jako jednu instanci a otevře ji po každém skenu.

Jakmile se dotknete pomocí zařízení paměťového čipu NFC, bude uvnitř aktivity provolána metoda override fun onNewIntent(intent: Intent). Z Intentu obdrženého v parametru metody můžete získat instaci Tag přes intent.getParcelableExtra(NfcAdapter.EXTRA_TAG).

Zaměřeno na NfcV technologii

Následující část již bude specifická pro technologii NfcV, kterou jsme použili pro náš účel. Pro komunikaci s NFC čipem potřebujete instanci třídy NfcV, kterou dostanete z tagu získaného v Intentu: val nfcV = NfcV.get(tag).

Pokud chcete zahájit komunikaci s NFC čipem, stačí zadat nfcV.connect(). Jestli chcete ukončit komunikaci, zadáte nfcV.close(). Jak jednoduché. Chcete-li číst/zapisovat data, využijte metodu nfcV.transceive(readParams : ByteArray). Parametry pro metodu transceive jsou v tomto procesu nejdůležitější. Můžete zde určit, zda chcete data číst či zapisovat, kolik bloků jich zapsat nebo číst, kde chcete začít zápis nebo čtení a tak dále. Jedná se o komplexní část, která může být specifikována v jednom z našich dalších článků.
Výsledkem metody transceive je rovněž ByteArray, které můžete převést na hexadecimální řetězec a poté zpracovat pro další účel.

Pokud zadávané parametry pro metodu transceive určují provést zápis, výstup metody bude určovat výsledek požadované operace. Jestli opět převedete tento výsledek na hexadecimální řetězec, získáte kód, který má pro úspěšný zápis tvar „00“. Podívejte se na kompletní dokumentaci s příkazy pro čtení a zápis, všechny výstupní kódy a mnoho dalšího.
Kódy odpovědí po provedení zápisu jsou dostupné konkrétně na stránce 22.

Užitečný tip na závěr

Máte-li otevřenou aplikaci a dotknete se zařízením čipu NFC, systém vám zobrazí systémový dialog pro výběr aplikace k provedení operace. To může být při opakovaném použití velmi otravné. Tento problém můžete vyřešit pomocí foreground dispatch systému, jehož zdrojový kód najdete v odkazu. Použijte ho. V kódu uvedeném v dokumentaci jsou použita stejná pravidla, jaká byla uvedena výše: Určete kategorii NFC s nejvyšší prioritou, kterou může váš čip podporovat a určete pouze ty technologie NFC, které používáte.

Věříme, že vám článek, ve kterém jsme ukázali několik základních rad pro práci s rozhraním NFC, pomůže při vaší práci.

Mohlo by se vám líbit