SMS senden und empfangen
Das Senden und Empfangen von Textnachrichten ist einer der am häufigsten genutzten Dienste auf Mobiltelefonen jeder Generation. Deshalb hat es mich umso mehr verwundert, dass man kaum Anleitungen zu diesem Thema findet, die dem Leser die verschiedenen Möglichkeiten Nachrichten zu senden (und zu empfangen) vorstellt, und auch auf die Unterschiede, Hintergründe, etc eingeht. Ich musste mir selbst all das was ich hier vorstellen werde Schnipselweise zusammensuchen. Und um euch das zu ersparen habe ich kurzerhand diesen Beitrag geschrieben.
Inhaltsverzeichnis[Verstecken] |
Einleitung
Worum geht´s? - Worum nicht?
Ich werde euch nicht erklären wie man Java-Programme schreibt, mit Eclipse, dem SDK, und dem Emulator umgeht. Das solltet ihr drauf haben. Ich habe auch nicht vor, eine komplette SMS-App - wie sie im App-Store zu finden sind - durchzuackern. Vielmehr will ich euch zeigen, welche Klassen und Methoden zum Versenden und Empfangen von Textnachrichten zur Verfügung stehen, wie sie (prinzipiell) funktionieren und wie sie angewendet werden, damit ihr am Ende selbst eure eigene SMS-App schreiben könnt.
Vorab-Exkurs: Intents
Was ist ein Intent?
Ein Intent ist eine Beschreibung einer Aktion oder Operation, die (jetzt, oder zu einem späteren Zeitpunkt) ausgeführt werden soll. Das bedeutet, man kann eine Aktion erstellen, die bei der Ausführung eine andere App oder einen Hintergrunddienst startet (nur mal als grobes Beispiel). Eine weitere wichtige Aufgabe von Intents ist die Weitergabe von Informationen. Wer sich intensiver mit dem Thema beschäftigen will, dem empfehle ich den Developer-Guide.
Struktur
Ein Intent selbst ist keine Aktion. Es enthält aber Informationen, die andere Anwendungen benötigen, um eine gewünschte Aktion ausführen zu können. Man nehme also einen String (der eine Aktion beschreibt - z.B. "DO_STH"), Daten, mit denen gearbeitet werden soll, und schnüre alles zu einem Intent-Paket. Dann übergibt man dieses Paket einer Anwendung, die den Rest erledigt. Es gibt noch viele weitere Elemente, die man dem Intent mitgeben kann, die ich aber jetzt nicht genauer erläutern will.
Ein weiterer wichtiger Punkt zum Thema Intents ist jedoch die Art, wie ein Intent ausgeführt wird.
Anmerkung: es ist leichter zu verstehen, wenn ich sage ein Intent wird "ausgeführt". Auch wenn ich gerade erklärt habe dass ein Intent selbst gar nicht ausgeführt wird.
Zurück zum Thema: Es gibt explizite und implizite Intents. Der Unterschied ist einfach. Explizite Intents sprechen eine (vom Entwickler) festgelegte Klasse an. Bei impliziten Intents entscheidet das System, welche Klasse (einfacher: welche Anwendung) angesprochen wird. Android verwaltet eine Liste, in der steht, welche App für welche Aktion infrage kommt. Gibt es zu einer Aktion mehrere Anwendungen, und ist keine als standard gekennzeichnet, überlässt das System dem Anwender die Wahl. Das folgende Bild habt ihr (so ähnlich) bestimmt schon einmal gesehen:
Codebeispiel explizite und implizite Intents:
//explizit:
Intent intent = new Intent("DO_STH", BeispielKlasse.class);
//implizit:
Intent intent = new Intent("DO_STH", Uri.parse("content://..."));
Wie wählt Android die Anwendung aus? Das geschieht über zusätzlich hinzugefügte Informationen wie ich bereits erwähnt habe. Dazu gehören unter anderem der Typ der übertragenen Daten, oder eine URI.
Anwendung
Man muss ein Beispiel gesehen haben um sich das vorstellen zu können:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("text/plain");
intent.putExtra("Inhalt", "Hello World!");
context.startActivity(intent);
In diesem Beispiel wird ein Intent erzeugt, und ein Typ zugewiesen. Dieser Typ bezieht sich auf die Daten die hier mit putExtra mitgegeben werden (genaueres dazu später). Android sucht dann nach Anwendungen, die Text darstellen können.
Damit das System weiß, dass die Daten dargestellt und nicht gelöscht, gesendet oder sonstwie verarbeitet werden sollen, muss man die Aktion bestimmen. Dies geschieht über den Intent-Konstruktor. Diesem wird ein String übergeben (wie im Beispiel gezeigt), der die Aktion beschreibt. Hier ist das der String ACTION_VIEW aus der Klasse Intent mit dem Wert "android.intent.action.VIEW".
! Das Code-Beispiel funktioniert so nicht ! Es ist lediglich ein Beispiel, wie ein Intent erzeugt wird, und was das System damit macht.
Noch ein Hinweis zum Aufruf von startActivity: startActivity ist eine Methode der Klasse Context. Es muss also irgendein Objekt vom Typ Context verfügbar sein, auf dem die Methode aufgerufen wird (wie im Beispiel die Variable context).
Die standard SMS-App
So. Jetzt zum eigentlichen Thema. Und zwar gaaanz von vorne. Auf jedem Android-Handy - und auch allen die kein solches sind - gibt es eine vorinstallierte SMS-App mit der ihr sofort nach Herzenslust lossimsen könnt.
Ein großes Ärgernis beim Programmieren ist die Tatsache, dass man sich stundenlang durch Dokumentationen wühlen muss und verzweifelt versucht, noch die letzten Fehler auszumerzen. Es geht aber auch einfacher! Outsourcing ist das Motto! Dem ein oder anderen ist es gar nicht so wichtig dass die eigene App sämtliche Funktionen anbietet (vor allem wenn sie nebensächlich sind), solange der Anwender ohne Umstände ans Ziel kommt.
Die standard SMS-App aufrufen
Hier kommen auch schon die Intents ins Spiel! Mit folgendem Code könnt ihr den Anwender eurer App einfach an die standard SMS-App des Systems weiterleiten:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
context.startActivity(intent);
Da keine weiteren Daten übergeben werden, sind sämtliche Eingabefelder leer. Wie bereits erklärt wird dem Konstruktor der Befehl zum Anzeigen eines Inhalts übergeben ("android.intent.action.VIEW"), und ein Typ gibt an, um welche Art von Inhalt es sich handelt. Ich konnte in der Dokumentation nichts genaues über die Typen finden, die Android unterstützt. Ich kann also nicht garantieren, dass dieses Beispiel überall funktioniert. Möglicherweise ist der Typ der hier mit "vnd.android-dir/mms-sms" beschrieben wird in manchen Geräten nicht verfügbar oder wird anders bezeichnet.
Argumente übergeben
Wer einen Schritt weiter gehen möchte und eine eigene Oberfläche für das Senden einer SMS bereitstellt (zur Eingabe von Empfänger und Nachricht), die Drecksarbeit aber trotzdem an die standard SMS-App abgeben will, kann das gerne tun!
Dazu muss der obige Code nur um zwei kleine Zeilen erweitert werden:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setType("vnd.android-dir/mms-sms");
intent.putExtra("address", "15555215556");
intent.putExtra("sms_body", "Hello World!");
context.startActivity(intent);
Dem Intent werden hier Extras übergeben. Diese werden als Schlüssel-Wert-Paare gespeichert. Wie man sieht, ist der Schlüssel des ersten Eintrags der String "address", und der dazugehörige Wert (ebenfalls ein String) die Handy-Nummer des Empfängers. Der Schlüssel des zweiten Eintrags ist "message" und der Wert die Nachricht, die gesendet werden soll.
Diese Schlüssel sind nicht willkürlich gewählt! Man darf sie also nicht einfach durch andere ersetzten. Schließlich muss die empfangende Anwendung die Werte kennen!
Was wir selbst noch nicht brauchen - ich aber der Vollständigkeit halber und zum besseren Verständnis an dieser Stelle hinzufügen will - ist der Code, der (Prinzipiell) in der Anwendung die den Intent entgegennimmt (hier also die standard SMS-App), ausführt wird.
Bundle bundle = intent.getExtras();
String address = (String)bundle.get("address"); //Nummer abfragen
String message = (String)bundle.get("message"); //Nachricht abfragen
//address und message an Eingabefelder übergeben
Die Aktionen SEND und SENDTO
Ich will euch nicht die hintersten Ecken des Kaninchenbaus zeigen, aber ihr sollt einen Überblick über die Möglichkeiten bekommen, die Android im zusammenhang mit dem Versenden von SMS anbietet.
So auch die in der Klasse Intent definierten Aktionen ACTION_SEND und ACTION_SENDTO. Im gegensatz zu den oben gezeigten Beispielen folgen die Beispiele zu diesen Aktionen den Empfehlungen der Android-Dokumentation und sollten daher auch garantiert funktionieren.
Wird ein Intent mit der Aktion ACTION_SEND ausgeführt, ist nur festgelegt, was gesendet wird, aber nicht an wen. Der Empfänger wird erst in der aufgerufenen Anwendung gewählt.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "Hello World!");
startActivity(intent);
Da der Typ nicht SMS spezifisch ist, sondern allgemein Texte beschreibt, kann es sein, dass - je nachdem welche Apps ihr installiert habt - das System auch eine Anwendung zum Senden von E-Mails vorschlägt.
Die Aktion ACTION_SENDTO verhält sich gegensätzlich zu ACTION_SEND. Hier wird der Empfänger angegeben, und die Nachricht erst in der aufgerufenen Anwendung hinzugefügt.
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("sms:15555215556"));
startActivity(intent);
Ebenfalls anders als bei ACTION_SEND werden weder Typ noch Extras angegeben. Stattdessen wird eine URI übergeben, die als Schema "sms" und als Pfad die Handy-Nummer des Empfängers enthält. Durch die URI kann das System die Absicht des Intents nachvollziehen und die entsprechende Aktion auslösen.
Der Einsatz von Intents ist nicht ganz trivial wie ihr sehen könnt. Ihr müsst ein bisschen mit den verschiedenen Aktionen, Typen, und Extras experimentieren um das gewünschte Ergebnis zu erzielen.
SMS senden
Kommen wir zum Thema das wohl die meisten von euch interessiert: Wie kann ich über meine eigene App SMS versenden? Das funktioniert erstaunlich einfach:
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage("15555215556", null, "Hello World!", null, null);
Gut - Ganz so einfach wie es auf den ersten Blick aussieht ist es dann doch nicht. Denn wenn ihr diesen Code ausführt, wird euch garantiert eine Exception um die Ohren fliegen. Bisher hat die standard SMS-App das Senden der SMS übernommen. Und die darf das auch. Ihr dürft das nicht! Zumindest nicht einfach so.
Berechtigungen
Wenn eure App Daten von anderen Anwendungen oder dem System selbst lesen, schreiben oder löschen will, oder einfach nur auf Funktionen des Gerätes zugreifen will, muss das explizit erlaubt werden (permission = Erlaubnis). Dazu müsst ihr die Datei Manifest.xml ändern.
<manifest ... >
<uses-permission android:name="android.permission.SEND_SMS" />
<application ... >...</application>
</manifest>
Vor dem application-Tag müsst ihr zu eurer App passende uses-permission-Tags (wie im Beispiel gezeigt) einfügen. Das Attribut android:name definiert die verwendete permission.
Jetzt sollte es funktionieren. Aber moment - woher weiß ich, dass die SMS auch wirklich gesendet wurde? Im "Postausgang" der standard SMS-App liegt sie jedenfalls nicht. Und da wird sie auch nie sein. Denn es gibt nicht den SMS-Ordner, unter dem sämtliche SMS verwaltet werden. Das macht jede Anwendung selbst. Wenn ihr über eure App eine SMS sendet und sie jemals wieder sehen wollt, müsst ihr sie in eine eigene Datenbank, oder die einer anderen Anwendung schreiben. Dafür braucht ihr wieder extra Berechtigungen, müsst über Content-Provider auf die Datenbank zugreifen, usw. Aber darum geht´s hier nicht.
Fehlerfälle abfangen
Um zu überprüfen ob die SMS gesendet wurde, oder ob der Vorgang (z.B. wegen schlechtem Empfang) abgebrochen wurde, muss man die entsprechenden Meldungen abfangen.
An diesem Punkt müssen wir uns die Methode sendTextMessage nochmal genauer ansehen. In der Dokumentation steht folgendes:
public void sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
Das bedeutet:
- destinationAddress
- klar. Die Nummer des Empfängers
- scAddress
- die Nummer des Service-Centers, über welches die Nachricht geschickt werden soll. Das ist aber nicht interessant. Wir übergeben null und die SMS wird über das Standard-Service-Center gesendet.
- text
- der Nachrichtentext.
- sentIntent
- ein Intent, der als Broadcast versendet wird, wenn die Nachricht erfolgreich gesendet, oder der Versand abgebrochen wurde.
- deliveryIntent
- ein Intent, der als Broadcast versendet wird, wenn die SMS an den Empfänger gesendet wurde.
Nochmal zum Verständnis: Ein SMS wird nicht direkt an ein anderes Handy geschickt, sondern zuerst an eine Art SMS-Zentrale. Das ist das Service-Center (SMSC). Dort wird die Nachricht solange gespeichert, bis der Empfänger erreichbar ist (das Handy des Empfängers könnte ja ausgeschaltet sein, oder der Empfang ist schlecht).
Nachdem eine SMS an das Service-Center gesendet wurde, schickt dieses eine Bestätigung zurück, dass die Nachricht korrekt übermittelt wurde (noch nicht dem Empfänger zugestellt). Davon bekommt man normalerweise nichts mit. Außer ihr habt die Funktion aktiviert, dass die Status-Report-Nachrichten angezeigt werden sollen. Das Gerät nimmt diese Meldung entgegen, und versendet den angegebenen Intent als Broadcast (wie genau das abläuft kann ich euch nicht erklären). Den Broadcast können wir mit einem BroadcastReceiver abfangen (dazu später mehr). Das selbe passiert, wenn die SMS vom Service-Center an den Empfänger zugestellt wird. Dann bekommen wir die Mitteilung, dass die SMS angekommen ist.
Wir wollen nun herausfinden, ob eine SMS erfolgreich gesendet wurde, und ob sie der Empfänger erhalten hat. Dazu erstellen wir zwei Objekte vom Typ PendingIntent. Das sind Intents, die erst zu einem späteren Zeitpunkt ausgeführt werden.
PendingIntent piSent = PendingIntent.getBroadcast(context, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered = PendingIntent.getBroadcast(context, 0, new Intent("SMS_DELIVERED"), 0);
Was tun wir hier genau? Wir erzeugen ein Intent mit der Aktion SMS_SENT, und ein Intent mit der Aktion SMS_DELIVERED. Diese Aktionen (also die Beschreibung durch den String) können wir selbst definieren. Statt "SMS_SENT" könnte man auch "fertig" schreiben.
Da wir die Methode getBroadcast verwenden, können die Intents später über einen BroadcastReceiver empfangen werden. Zusätzlich können dieser Methode Codes und Flags übergeben werden (unwichtig - Details in der Doku).
Mit dieser Zeichnung kann man sich das besser vorstellen:
Ok - das ist viel auf einmal und auf Anhieb schwer zu verstehen. Darum jetzt nochmal ein Beispiel gaaanz langsam zum Mitschreiben:
Wir schreiben eine Methode sendSMS, die eine Nachricht versenden soll. Empfänger und Text wurden bereits eingegeben und werden dieser Methode übergeben.
public void sendSMS(String phoneNumber, String message)
{
PendingIntent piSent = PendingIntent.getBroadcast(context, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered = PendingIntent.getBroadcast(context, 0, new Intent("SMS_DELIVERED"), 0);
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage(phoneNumber, null, message, piSent, piDelivered);
}
Jetzt müssen wir einen BroadcastReceiver schreiben, um die Intents zu empfangen. Dazu erstellen wir am besten eine neue Klasse mit dem Namen StatusReceiver. Diese müssen wir von BroadcastReceiver ableiten und die abstrakte Methode onReceive definieren.
public class StatusReceiver extends BroadcastReceiver
{
public void onReceive(Context cxt, Intent intent)
{
int short = Toast.LENGTH_SHORT;
if(intent.getAction().equals("SMS_SENT"))
{
switch(getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(cxt, "SMS sent", short).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(cxt, "Generic failure", short).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(cxt, "No service", short).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(cxt, "Null PDU", short).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(cxt, "Radio off", short).show();
break;
}
}
else if(intent.getAction().equals("SMS_DELIVERED"))
{
switch(getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(cxt, "SMS delivered", short).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(cxt, "SMS not delivered", short).show();
break;
}
}
}
}
Sobald dieser BroadcastReceiver einen Broadcast empfängt, wird die Methode onReceive mit dem Context und dem Intetnt (aus sendSMS) aufgerufen. Nun können wir die Aktion des Intents abfragen um zu entscheiden, was was wir tun wollen. Der Result-Code (also der Code der Status-Nachricht) wird über die Basisklasse abgerufen. Wie genau das abläuft weiß ich nicht.
Abhängig vom Code kann dann eine entsprechende Meldung ausgegeben werden (nur als Beispiel).
Receiver registrieren
Damit das alles auch funktioniert, muss der StatusReceiver als BroadcastReceiver im System registriert werden. Das geschieht wieder in der Manifest.xml.
<application ... >
<activity>...</activity>
<receiver android:name=".StatusReceiver">
<intent-filter>
<action android:name="SMS_SENT" />
<action android:name="SMS_DELIVERED" />
</intent-filter>
</receiver>
</application>
Wir erstellen also ein receiver-Tag, in dem wir den Klassennamen des StatusReceivers eingragen. Innerhalb dieses Tags ist ein intent-filter dafür zuständig, dass nur die dort definierten Aktionen an den Receiver weitergegeben werden.
Das Ergebnis sieht dann etwa so aus:
Wenn ihr einen BroadcastReceiver über die Manifest.xml - so wie ich euch das gerade gezeigt habe - registriert, ist er ab dem Zeitpunkt der Installation fest verankert und kann nicht mehr gelöscht werden. Außer ihr deinstalliert die App wieder.
Aber es geht auch anders. BroadcastReceiver können auch dynamisch (also im Programmverlauf) registriert und entfernt werden. Sie sind dann nur solange aktiv wie ihr das wollt. Nur als Information am Rande.
SMS empfangen
Wie ihr euch vielleicht schon denken könnt, kann man die BroadcastReceiver nicht nur für die Status-Nachrichten verwenden. Sie werden ebenfalls benötigt, um eine SMS empfangen zu können. Das Vorgehen ist das gleiche wie bei den Status-Meldungen.
Wir schreiben eine Klasse SMSReceiver und leiten sie von BroadcastReceiver ab.
<code>
public class SMSReceiver extends BroadcastReceiver
{
public void onReceive(Context cxt, Intent intent)
{
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
{
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[messages.length];
for (int n = 0; n < messages.length; n++)
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
String toast = "Received SMS from: " + smsMessage[0].getDisplayOriginatingAddress();
toast += "\nMessage: " + smsMessage[0].getDisplayMessageBody();
Toast.makeText(context, toast, Toast.LENGTH_LONG).show();
}
}
}
</code>
Was tun wir genau? Zunächst prüfen wir (wie oben), ob der empfangene Intent die gewünschte Aktion enthält. Danach rufen wir die im Intent gespeicherten Extras ab. Wie bereits erklärt, werden die Daten als Schlüssel-Wert-Paare gespeichert. Die Nachricht ist durch den Schlüssel "pdus" abrufbar. PDU bedeutet protocol description unit. Dabei handelt es sich (grob gesagt) um die SMS in binärer Form.
Wir erhalten die PDU in einem Object-Array. Die Einträge (sollte nur einer sein) müssen dann zu einer Nachricht umgewandelt werden. Dazu verwenden wir die Methode createFromPdu der Klasse SmsMessage. Der Rest ist ein Kinderspiel. Einfach über die entsprechenden Methoden den Absender und die Nachricht abfragen, und beispielsweise über einen Toast anzeigen.
Das sieht dann so aus:
Ich weiß - das ist momentan schwierig nachzuvollziehen. Aber wenn man erst mal weiß was die PDU ist und wie alles zusammenhängt, ist es schon einfacher.
Berechtigungen
Auch für das Empfangen von SMS benötigt man eine Berechtigung. Diese wird wie beim Senden in die Manifest.xml eingetragen.
<manifest ... >
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application ... >...</application>
</manifest>
Receiver registrieren
Ebenso wie der StatusReceiver muss auch der SMSReceiver im System als gültiger Empfänger für Textnachrichten eingetragen werden.
<application ... >
<activity>...</activity>
<receiver android:name=".StatusReceiver">...</receiver>
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
Binäre SMS
Zu guter letzt will ich euch die Möglichkeit binäre SMS senden zu können nicht vorenthalten. Mit dieser Art von SMS habt ihr die Möglichkeit, nicht nur Text, sondern auch kleine Bilder und jede andere Art von Daten für eure eigene App zu senden. Im Gegensatz zu Textbasierten SMS werden binäre SMS nicht in der standard SMS-App angezeigt. Auch die Statusnachricht für den Empfang bleibt aus. Das liegt daran, dass binäre SMS nicht an den Port für Textbasierte SMS gesendet werden.
An welchen Port die SMS geschickt werden soll, bleibt dem Sender überlassen (also dem Entwickler). Natürlich muss die Anwendung, die auf den Eingang der binären SMS wartet, an dem entsprechenden Port lauschen.
Binäre SMS senden
Das Senden binärer SMS funktioniert fast genauso wie das Senden Textbasierter Nachrichten. Nur wird hier die Methode ''[1],%20android.app.PendingIntent,%20android.app.PendingIntent%29 sendDataMessage]'' verwendet.
Achtung! beachtet dass für die Nachricht einer SMS (auch für binäre) eine maximale Länge von 1120 Bit (140 Byte) vorgegeben ist.
Die Methode sendSMS könnte dann etwa so aussehen:
<code>
public void sendSMS(String phoneNumber, byte[] data, short Port)
{
//PendingIntents ...
SmsManager manager = SmsManager.getDefault();
manager.sendDataMessage(phoneNumber, null, Port, data, piSent, piDelivered);
}
</code>
Ein wichtiger Hinweis für alle, die den Code testen wollen: Aufgrund eines Bugs können im Android-Emulator keine binären SMS gesendet bzw. empfangen werden! Manchmal kommen sie als normale SMS an, was aber nicht sein sollte. Es wird auch keine Exception geworfen oder eine sonstige Fehlermeldung angezeigt. Es passiert einfach nichts. Mit diesem Problem hatte ich lange zu kämpfen, habe letztendlich doch eine Möglichkeit gefuneen, den Code zu testen (und ja - er funktioniert).
Ich habe die Anwendung einfach auf mein Android-Gerät kopiert und eine binäre SMS an meine eigene Handynummer gesendet. Und es hat funktioniert. Mein Handy hat die Nachricht wie jede andere an das SMSC gesendet, und dieses wieder an mich zurück. Es könnte aber auch sein, dass euer Handy schlau genug ist, und Nachrichten an euch selbst unterbindet.
Binäre SMS empfangen
Das Empfangen binärer SMS entspricht wieder dem Vorgehen, das wir von den Textbasierten Nachrichten kennen.
<code>
public class BinarySMSReceiver extends BroadcastReceiver
{
public void onReceive(Context cxt, Intent intent)
{
if(intent.getAction().equals("android.intent.action.DATA_SMS_RECEIVED"))
{
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[messages.length];
for (int n = 0; n < messages.length; n++)
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
byte[] data = msgs[i].getUserData();
//Daten verarbeiten
}
}
}
</code>
Berechtigungen
Für das Senden und Empfangen werden die selben Berechtigungen wie für Textbasierte SMS verwendet.
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Receiver registrieren
Für den Intent-Filter des BinarySMSReceivers ist außer der Aktion noch das Schema der zu empfangenden Daten, und der Port (in diesem Beispiel 8080) anzugeben.
<application ... >
<activity>...</activity>
<receiver android:name=".StatusReceiver">...</receiver>
<receiver android:name=".SMSReceiver">...</receiver>
<receiver android:name=".BinarySMSReceiver">
<intent-filter>
<action android:name="android.intent.action.DATA_SMS_RECEIVED" />
<data android:port="8080" />
<data android:scheme="sms" />
</intent-filter>
</receiver>
</application>
Zusammenfassung
Hier nochmal eine kurze Checkliste, die ihr für das Senden und Empfangen von Textnachrichten beachten müsst:
- Eingabedaten abfragen (Telefonnummer und Nachrichtentext)
- PendingIntents erzeugen
- Receiver für die Status-Nachrichten schreiben
- Receiver für eingehende Nachrichten schreiben
- Permissions angeben (Manifest.xml)
- Receiver registrieren (Manifest.xml)
- Nachricht über den SmsManager senden
Danke für´s Durchlesen und viel Spaß beim experimentieren! Falls ihr irgendwelche Fehler gefunden habt und es besser wisst, könnt ihr mich gerne korrigieren :-)
Bookmark / E-Mail
Klicke auf ein Icon, um diese Wiki-Seite zu bookmarken. » Diesen Artikel per E-Mail versendenKategorien
- Acer (2)
- AndroidPIT-Wiki: Ergänzungswürdige Seiten (2)
- AndroidPIT-Wiki: Zu löschende Seiten (5)
- Anleitungen (29)
- APN (12)
- Archos (1)
- Asus (2)
- Begriffserklärungen (17)
- Custom-Rom (1)
- Einstellungen (14)
- Entwicklung (11)
- Geräte mit NFC (5)
- Google (6)
- Handys mit NFC (3)
- Hardware (26)
- Hero (3)
- Hersteller (3)
- HTC (8)
- LG (2)
- Milestone (2)
- Motorola (3)
- Nexus-Geräte (6)
- NotionInk (1)
- Root (27)
- Samsung (7)
- Samsung Galaxy S i9000 (1)
- Sony Ericsson Xperia X10 Mini (5)
- Sony Ericsson Xperia X10 Mini Pro (8)
- Sony Ericsson Xperia X8 (2)
- Spiele (1)
- Tablet (20)
- Tablets mit NFC (2)
- Tipps und Tricks (12)
- Tools (6)
- Toshiba (1)
- User's Guide (1)
- Wiki (6)
- ZTE (1)
