Apps für Android programmieren leicht gemacht!
NFC-Tags beschreiben

NFC-Tags beschreiben

Heute habe ich einen ganz besonderen Leckerbissen für euch an Land gezogen, denn ich möchte euch gerne zeigen, wie man NFC-Tags beschreiben kann.
In diesem Artikel soll es vorerst nicht darum gehen, wie man diese wieder ausließt oder bei Kontakt auf einen NFC-Tag reagiert, vielmehr wollen wir die Befehle lediglich aus einen NFC-Tag schreiben. Alles andere folgt in weiteren Artikeln.

In diesem Artikel werden wir weit über die einfache Java Programmierung hinweg greifen und uns ansehen, wie wir externe Geräte/Speichermedien beschreiben.

 

Voraussetzungen:

Für diesen Artikel sind besondere Voraussetzungen nötig.
So müsst ihr nicht nur über eine Entwicklungsumgebung und ein Android Smartphone verfügen.
Das Android Smartphone muss zusätzlich über ein NFC-Lesegerät verfügen und ihr benötigt NFC-Tags zuhause, die ihr beschreiben könnt.

Wenn euer Handy NFC unterstützt findet ihr eine entsprechenden Menüpunkt in den Einstellungen oder ihr fragt kurz Google.

Falls ihr noch keine NFC-Tags Zuhause rumfliegen habt kann ich euch die NFC Anhänger von Chafon empfehlen. Diese sind Wasserdicht, sehr günstig und du bekommst gleich 12 Stück davon. Die Tags findet du Hier -> Klick Alternativ gäbe es noch sehr günstige NFC-Aufkleber. Diese sind leider nicht Wasserdicht. Persönlich habe ich etwas dagegen mir meine Wohnung voll zu kleben, aber Preis-Leistung stimmt hier einfach. Die Tags findest du hier -> Klick

 

NFC-Tags beschreiben:

Nun, da wir alles nötige beisammen haben können wir ja anfangen zu programmieren oder etwa nicht?
Naja so halb.
Wir müssen in unserer App noch einige kleinere Vorbereitungen treffen, damit unsere App überhaupt die Möglichkeit bekommt NFC-Tags beschreiben zu können.

Als erstes benötigen wir die Berechtigung von Android, NFC nutzen zu dürfen. Diese Berechtigung holen wir uns ein, indem wir folgenden Tag in die Datei „AndroidManifest.xml“ hinzufügen:

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

Falls wir unsere App im PlayStore veröffentlichen möchten und unsere App nur für Geräte mit NFC angezeigt werden soll nutzen wir zusätzlich folgenden Tag:

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

Dieser Tag ist nicht zwangsläufig notwenig, schließt schon im PlayStore allerdings alle Geräte aus, die kein NFC besitzen und das erspart uns vielleicht etwas Arbeit.
Wir benutzen in dieser Anleitung übrigens die minimale API Version von 16 für diese App. Wir nutzen dort später eine Funktion, welche erst unter der API 16 eingeführt wurde.

 

Programmierung:

So, nun können wir dann aber endlich einmal beginnen zu programmieren.

Wir müssen uns die Machanik der Android App wie folgt vorstellen:
Als erstes geben wir einen Text in ein Textfeld ein. Anschließend wird auf einen Knopf geklickt und die App wartet auf den NFC-Tag.
Hier schaltet sich ein Listener hinzu, welcher erkennt wenn ein NFC-Tag ans Handy gehalten wird, während die App geöffnet ist.
Nun wird der Tag formatiert und beschrieben, falls er noch leer ist.
Falls der Tag bereits mit einem Text beschrieben ist wird lediglich der Text ersetzt.

Vielleicht sollten wir damit anfangen einige kleine Variablen zu definieren, da wir sie später dringend benötigen.

//Später zur Prüfung verwendet
boolean darfSchreiben = false;

//Benötigt, um eine Funktion beim Erkennen eines NFC-Tags auszulösen
private NfcAdapter NfcAdapter;
private PendingIntent NfcPendingIntent;

//Benötigt, um eine dauerhafte Nachriht anzeigen und abbrechen zu können
private AlertDialog.Builder dialogBuilder;
private AlertDialog dialog;

 

Die Methode „onCreate“ kann belassen werden wie sie ist.

Anschließend müssen wir die von AndroidStudio erstellte Datei activity_main.xml etwas anpassen. Wir benötigen einen Knopf, welcher eine Funktion auslöst, und ein Textfeld, in das wir unsere Nachricht eingeben können.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />

    

    <EditText
        android:id="@+id/value"
        android:hint="Value"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=" Droid-Lernen.de ist klasse!"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Schreiben"
        android:id="@+id/button"
        android:onClick="schreibenKnopf"
        android:layout_below="@+id/value"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

Bei dem Klick auf den Button wird durch den Eintrag

android:onClick="schreibenKnopf"

die Methode „schreibeKnopf“ in der Datei „MainActivity.class“ ausgeführt. Diese muss nun von uns hinzugefügt werden.

public void schreibenKnopf(View v){
    
    //Registriert einen Adapter und ein Intent, durch die es möglich wird NFC-Tags zu erkennen.
    //Vorteil ist, dass die momentan geöffnete App beim Erkennen von NFC-Tag priosiert behandelt wird.
    NfcAdapter = NfcAdapter.getDefaultAdapter(MainActivity.this);
    NfcPendingIntent = PendingIntent.getActivity(MainActivity.this, 0, new Intent(MainActivity.this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
    IntentFilter[] NfcFilter = new IntentFilter[] { tagDetected };
    NfcAdapter.enableForegroundDispatch(this, NfcPendingIntent, NfcFilter, null);
    
    //Erlaube das Schreiben, in einer späteren Methode
    darfSchreiben = true;
    
    //Öffne ein Dialogfeld, welches zum nähern des NFC-Tags auffordert.
    dialogBuilder = new AlertDialog.Builder(MainActivity.this);
    dialogBuilder.setTitle("Warte auf den NFC Tag.");
    dialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            verbieteSchreiben();
        }

    });
    dialog = dialogBuilder.create();
    dialog.show();
    
}

 

Mit der folgenden kleinen Methode wird das Beschreiben von NFC-Tags übrigens wieder deaktiviert und andere Apps bekommen die vorrangige Behandlung mit NFC-Tags:

private void verbieteSchreiben() {
    darfSchreiben = false;
    NfcAdapter.disableForegroundDispatch(this);
}

 

Nun können wir bereits das Beschreiben von NFC-Tags starten und stoppen, aber bisher können wir weder NFC-Tags beschreiben, noch haben wir eine Methode, die einen NFC-Tag behandelt.
Aus diesem Grund gibt es die bereits festgelegte Methode „onNewIntent“, die aufgerufen wird, weil wir in „schreibenKnopf“ ein Intent registriert haben.

@Override
    protected void onNewIntent(Intent intent) {
        //Prüfe ob der NFC-Tag beschreiben werden darf
        if (darfSchreiben == true && NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {

            //Bekomme eine Variable mit dem Tag, um ihn später beschreiben zu können
            Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

            //erstellt eine Formatierung (in unserem Fall die Formatierung eines Textes)
            NdefRecord record = NdefRecord.createMime("text/plain", ((TextView)findViewById(R.id.value)).getText().toString().getBytes());
            NdefMessage message = new NdefMessage(new NdefRecord[] { record });

            //Beschreibe den NFC-Tag mit der Methode "beschreibeTag" und schließe das Dialogfeld, wenn die Methode richtig gearbeitet hat
            if (beschreibeTag(message, detectedTag)) {

                //Gibt eine Meldung aus
                showToast("Der Tag wurder erfolgreich beschrieben.");

                //Schließt das Dialogfeld
                dialog.dismiss();

                //Schaltet das weitere Beschreiben von Tags ab, da bereits ein Tag beschrieben wurde
                darfSchreiben = false;
            }
        }
    }

Im letzten großen Schritt benötigen wir allerdings immernoch unser Herzstück der App. Uns fehlt nämlich weiterhin eine Methode, die einen NFC-Tag wirklich beschreibt.

public boolean beschreibeTag(NdefMessage text, Tag tag) {
    int textGroesse = text.toByteArray().length;
    try {
        Ndef ndef = Ndef.get(tag);

        //prüfe ob der NFC-Tag bisher unformatiert war
        if (ndef != null) {
            //Der Tag war bereits formatiert
            ndef.connect();

            //gebe einen Fehler aus, wenn der NFC-Tags über einen Schreibschutz verfügt
            if (!ndef.isWritable()) {
                showToast("Fehler: Dieser Tag darf nicht beschrieben werden.");
                return false;
            }

            //gebe einen Fehler aus, wenn die Nachricht größer ist, als der Spiecherplatz des NFC-Tags
            if (ndef.getMaxSize() < textGroesse) {
                showToast("Fehler: Dieser Tag hat nicht genug Speicherplatz.");
                return false;
            }

            //schreibe die Nachricht auf den NFC-Tag
            ndef.writeNdefMessage(text);

            return true;
        } else {
            //Der tag war bisher noch nicht formatiert
            NdefFormatable format = NdefFormatable.get(tag);
            if (format != null) {
                try {
                    //beschreibe den NFC-Tag
                    format.connect();
                    format.format(text);
                    return true;
                } catch (IOException e) {
                    return false;
                }
            } else {
                return false;
            }
        }

    } catch (Exception e) {
        return false;
    }
}

 

Alles was jetzt nich fehlt ist die Methode, die uns kleinere Meldungen am unteren Bildschirmrand anzeigt. Die sogenannten Toasts.

//Diese Methode gibt eine einfache Meldung aus. (Unterer Bildschirmrand)
public void showToast(String nachricht){
    Toast.makeText(getApplicationContext(), nachricht, Toast.LENGTH_SHORT).show();
}

Und schon ist unsere App zum beschreiben eines NFC-Tags fertig.

NFC-Tags Beschreiben


Lade dir kostenfrei den Source Code zu diesem Artikel herunter und lerne, wei man unter Android NFC-Tags beschreiben kann.

DownloadLizenzbedingungen

Marvin

Ich bin 23 Jahre jung und studiere zurzeit Wirtschaftsinformatik an der Georg-August-Universität in Göttingen. Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

Kommentar hinzufügen

*Pflichtfeld