Für die Entwicklerkonferenz IO-2013 hat Google eine Art Schnitzeljagd veranstaltet, um die praktische Nutzung von NFC zu demonstrieren. Die Teilnehmer brauchten dafür ein NFC-fähiges Android und haben sich dann eine App mit Namen „NFC-Hunt“ installiert. Die App gab Hinweise, wo in der realen Umgebung NFC-Tags zu finden sind. Diese Tags mussten gefunden und gescannt werden, worauf die App Hinweise für die nächste Station gab.

Google hat den Quelltext von NFC-Hunt dankenswerterweise veröffentlicht. Man hat damit ein schönes Beispiel wie eine echte NFC-Anwendung zu programmieren ist. Als ich den Quelltext nachvollziehen wollte fielen mir Lücken in der Dokumentation auf. Gerade die interessanten Teile musste ich relativ mühsam zusammensuchen: wie erreiche ich es, dass meine App auf NFC-Tags lauscht und wie reagiere ich dann. Hier kommt jetzt das Ergebnis meiner Recherche:

Diagram with Manifest, Android-OS, NFC-Tag, NFCShimActivity and ClueActivity

Schritt 0: Die App meldet im Manifest Interesse an den NFC-Nachrichten an. Das passiert ohne das die App läuft. Das Manifest legt fest welche Activity die NFC-Daten bekommen soll:

<activity android:name=".NFCShimActivity"
            android:theme="@android:style/Theme.NoDisplay">      
<intent-filter>
  <action android:name="android.nfc.action.NDEF_DISCOVERED" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:scheme="https" android:host="nfchunt.appspot.com"
                    android:pathPrefix="/f" />
</intent-filter>
	...
</activity>

Außerdem wird natürlich spezifiziert, das die App auf die NFC zugreifen möchte:

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

Bei manchen Apps ist NFC nur eine optionale Funktion. Speziell diese App macht jedoch ohne NFC-fähige Hardware keinen Sinn, deshalb gibt es noch folgenden Eintrag:

<uses-feature android:name="android.hardware.nfc" android:required="true" />

Schritt 1: Der NFC-Tag enthält im Daten im NDEF-Format. In unserem Fall ist das ein „Bookmark“, also eine URL. Die gewählte URL besteht aus einem jeweils gleichen Anfang und einen für jeden Tag verschiedenen Datenteil, wie bei HTTP-GET-Parametern.

https://nfchunt.appspot.com/f?c=CLUENAME

Das System erkennt den NFC-Tag, analysiert den Typ der Nachricht und ermittelt, welche App dafür zuständig ist. Wenn unsere NFC-Hunt-App noch nicht installiert wäre, würde der Browser gestartet, die angegeben URL laden und so eine die Seite mit der Beschreibung des Spiels zeigen.

Schritt 2: Das System ruft die im Manifest spezifizierte Activity auf. Im NFC-Hunt wird dafür eine minimale Activity ohne UI definiert, die NFCShimActivity.

Diese Activity analysiert die erhaltenen Daten. Sie steckt die Daten in ein Intent. Das Intent wird jetzt an die eigentliche Activity mit dem UI geschickt. (Schritt 3)

Dieser Zwischenschritt ermöglicht eine Entkoppelung der externen NFC-Daten und Formate vom Geschehen im Rest der App. Man hat sogar die Möglichkeit, den Intent an eine ganz andere App zu schicken und ihr so neue NFC-Fähigkeiten zu verleihen.

Schritt 4: Das System ruft die eigentliche Activity auf, in unserem Fall die ClueActivity. Wenn die Activity schon vorher sichtbar ist, dann wird Android dabei normalerweise eine zweite Instanz der Actvity starten und man sieht dann ein zweites Fenster aufpoppen.

In unserem Fall soll eine schon sichtbarer Bildschirm sichtbar bleiben, aber mit den neu erhalten Daten aktualisiert werden. Die Activity bekommt deshalb im Manifest das Attribut

android:launchMode="singleTask"

Normalerweise erhalten wir Zugriff auf die Daten des Intent in der onCreate()-Methode, jetzt wird onCreate() aber nicht mehr ein zweites mal aufgerufen. Wir müssen deshalb die Methode onNewIntent() überschrieben, dort merken wir uns die übergebenen Daten.

public void onNewIntent(Intent intent) {....}

Schritt 5: Im Folgenden ruft Android die onResume() Methode nochmal auf, dort reagieren wir schließlich auf die Daten, ändern den Spielstatus und zeigen die gefundenen Tags mit updateTagDisplay() an. (Schritt 6)

Fazit

Das in NFC-Hunt demonstrierte Vorgehen stellt sicher nur eine Möglichkeit dar, wie man mit NFC-Tags interagieren kann. Für viele Anwendungen liefert es ein durchaus brauchbares Gerüst.

Schreibe einen Kommentar