21.05.2014
Für das Importieren von Kontakten in das Android-Adressbuch gibt es unterschiedliche Wege. Es gibt die Möglichkeit über ContentValues die Kontaktinformationen anzulegen und anschließend über den Android-ContentResolver den Kontakt hinzuzufügen. Hierfür müssen aber alle Werte einzeln angelegt und entsprechenden Konstanten von Android zugewiesen werden. Somit ist die vCard zuerst zu parsen und für jedes Element eine Bedingung, die zur richtigen Konstanten führt, anzulegen. Das ist bei sich ändernden vCard-Versionen schwer erweiterbar und wartbar. Daher ist der gewünschte Weg ein direkter Import der vCard. Dafür ist eine nahe liegende Lösung ein Content Provider.
Content Provider
Ein Content Provider verwaltet den Zugriff auf strukturierte Daten. Er kapselt die verfügbaren Daten und ermöglicht so die Definition von Sicherheitsmechanismen. Seine Funktionaltität wird auf Content Providers definiert. Demnach wird eine Zugriffskontrolle vereinfacht, welche bei der Anwendung des Content Provider eine große Rolle spielt. Er dient als Schnittstelle zwischen verschiedenen Prozessen, die Daten untereinander austauschen wollen. Auch vCards sind Daten, die mit dieser Technik ausgetauscht werden können. So bietet Android Content Provider an, um Audio-, Videodateien oder Bilder und auch persönliche Kontakte zu importieren. Für letztere steht der Contacts Provider zur Verfügung. Ihm können mit Hilfe eines impliziten Intents der eigene Content Provider mit angehängtem vCard-String übergeben werden. Er parst die vCard und fügt sie dem internen Adressbuch hinzu. Dabei entsteht eine Benachrichtigung in der Taskleiste des Smartphones. Außerdem wird der vCard-Text dem Benutzer anschließend für wenige Sekunden angezeigt. Da dies ein sehr unschönes Verhalten ist und nicht dem Wunsch nach einem transparenten Import entspricht habe ich eine Alternative implementiert, die das umgeht.
NFC-Simulation
Um einen transparenten Import zu ermöglichen, kann ein Parser für vCards implementiert werden. Da dies ein komplexer Vorgang ist und der Parser mit der Version von Android kompatibel sein muss, könnte der Quellcode des Android-Parsers kopiert werden. Der Parser besteht aus 22 Klassen, welche quelloffen sind. Das Grundgerüst bilden dabei die Klassen VCardParserImpl_Vx, welche für die unterschiedlichen vCard-Versionen verfügbar sind. Die vCards können anhand der Klassen in die entsprechenden Android-Befehle umgewandelt und in das Kontaktbuch importiert werden. Durch das Kopieren der Quellcode-Dateien entstehen aber große Mengen an Code-Redundanzen, welche zu vermeiden sind. Außerdem ist der Code aktuell zu halten und muss bei jeder neuen Android-Version gewartet und erneut hinzugefügt werden.
Bei mehreren Tests, bei NFC-Tags mit unkomprimierten Kontaktdaten an das Smartphone geführt werden, ist zu erkennen, dass der Import von NFC-Kontakten automatisch geschieht. Das ist darauf zurückzuführen, dass die Telefonbuch-Applikation von Android den Import ohne weitere Meldungen vollzieht. Um die Daten in das Telefonbuch zu importieren, kann der Scan-Vorgang eines NFC-Tags simuliert werden. Dadurch wird der Kontakt-Applikation des Smartphones suggeriert, dass ein NFC-Tag an das Smartphone geführt wurde und sie übernimmt den automatischen Import. In Folge dessen ist keine weitere Wartung bei veränderter vCard-Version notwendig, da der interne Import von Android verwendet wird.
Zum Simulieren des NFC-Tags ist die Android-Kontakt-Applikation zu analysieren. Im Package mit dem Namen „vcard“ befindet sich unter anderem die Datei NfcImportVCardActivity.java. Dort ist in der onCreate-Methode, welche zu Beginn der Activity aufgerufen wird, zu erkennen, dass das eingehende Intent auf die Konstante ACTION_NDEF_DISCOVERED überprüft wird. Somit ist ein eigenes Intent zu senden, welches als Aktion dieselbe besitzt. Die Bedingungen in den folgenden Zeilen sind für die Erstellung des Intents maßgebend. So ist zu erkennen, dass der Datentyp auf den Wert „text/x-vcard“ oder „text/vcard“ zu setzen ist und die Kontaktdaten in einem speziellen Array-Format vorliegen müssen. Sind all die Bedingungen erfüllt, so wird der Kontakt direkt importiert. Es ist also ein solches Intent zu erzeugen. Da auf die Aktion ACTION_NDEF_DISCOVERED aber mehrere Applikationen registriert sind muss ein explizites Intent gestartet werden. Daher werden alle Activities, die auf das erzeugte Intent registriert sind ausgelesen. Ist die Kontakt-Applikation verfügbar, so wird sie als Ziel-Klasse festgelegt und das Intent wird gestartet.
Da das aus dem Quellcode der Kontakt-Applikation entwickelte Intent allgemeingültig verwendet werden kann, sind dessen wichtigste Elemente im Folgenden festgehalten:
1 2 3 4 5 6 | intent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED); intent.setType(ContactsContract.Contacts.CONTENT_VCARD_TYPE); intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, <NdefMessage[]>); intent.setClassName(<app>.activityInfo.packageName, <app>.activityInfo.name); |
Das Intent kann für jegliche Art von Kontakt-Imports wiederverwendet werden. Sei es ein Import mit Hilfe einer direkten Benutzereingabe oder ein Kontakt, der von einem Smartphone zu einem anderen versendet werden soll. Eine Beschränkung auf NFC gibt es dabei nicht. Sollte die Kontakt-Applikation nicht verfügbar sein so kann die Ausweichmöglichkeit über einen Content Provider verwendet werden.
Kategorie: News, Programmierung |
Schlagwörter: android, import, kontakt, notification