Ich habe herausgefunden, wie man SMS-Nachrichten sendet und empfängt. Um SMS-Nachrichten zu senden, musste ich die sendTextMessage()
und sendMultipartTextMessage()
Methoden der SmsManager
Klasse aufrufen . Um SMS-Nachrichten zu empfangen, musste ich einen Empfänger in der AndroidMainfest.xml
Datei registrieren . Dann musste ich die onReceive()
Methode der überschreiben BroadcastReceiver
. Ich habe unten Beispiele aufgeführt.
MainActivity.java
public class MainActivity extends Activity {
private static String SENT = "SMS_SENT";
private static String DELIVERED = "SMS_DELIVERED";
private static int MAX_SMS_MESSAGE_LENGTH = 160;
// ---sends an SMS message to another device---
public static void sendSMS(String phoneNumber, String message) {
PendingIntent piSent = PendingIntent.getBroadcast(mContext, 0, new Intent(SENT), 0);
PendingIntent piDelivered = PendingIntent.getBroadcast(mContext, 0,new Intent(DELIVERED), 0);
SmsManager smsManager = SmsManager.getDefault();
int length = message.length();
if(length > MAX_SMS_MESSAGE_LENGTH) {
ArrayList<String> messagelist = smsManager.divideMessage(message);
smsManager.sendMultipartTextMessage(phoneNumber, null, messagelist, null, null);
}
else
smsManager.sendTextMessage(phoneNumber, null, message, piSent, piDelivered);
}
}
//More methods of MainActivity ...
}
SMSReceiver.java
public class SMSReceiver extends BroadcastReceiver {
private final String DEBUG_TAG = getClass().getSimpleName().toString();
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private Context mContext;
private Intent mIntent;
// Retrieve SMS
public void onReceive(Context context, Intent intent) {
mContext = context;
mIntent = intent;
String action = intent.getAction();
if(action.equals(ACTION_SMS_RECEIVED)){
String address, str = "";
int contactId = -1;
SmsMessage[] msgs = getMessagesFromIntent(mIntent);
if (msgs != null) {
for (int i = 0; i < msgs.length; i++) {
address = msgs[i].getOriginatingAddress();
contactId = ContactsUtils.getContactId(mContext, address, "address");
str += msgs[i].getMessageBody().toString();
str += "\n";
}
}
if(contactId != -1){
showNotification(contactId, str);
}
// ---send a broadcast intent to update the SMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
}
}
public static SmsMessage[] getMessagesFromIntent(Intent intent) {
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++) {
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++) {
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
/**
* The notification is the icon and associated expanded entry in the status
* bar.
*/
protected void showNotification(int contactId, String message) {
//Display notification...
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myexample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.WRITE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:debuggable="true"
android:icon="@drawable/ic_launcher_icon"
android:label="@string/app_name" >
<activity
//Main activity...
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
//Activity 2 ...
</activity>
//More acitivies ...
// SMS Receiver
<receiver android:name="com.myexample.receivers.SMSReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
Ich habe mich jedoch gefragt, ob Sie MMS-Nachrichten auf ähnliche Weise senden und empfangen können. Nach einigen Recherchen werden viele Beispiele in Blogs einfach Intent
an die native Messaging-Anwendung übergeben. Ich versuche, eine MMS zu senden, ohne meine Bewerbung zu verlassen. Es scheint keine Standardmethode zum Senden und Empfangen von MMS zu geben. Hat jemand das zum Laufen gebracht?
Ich bin mir auch bewusst, dass der SMS / MMS ContentProvider nicht Teil des offiziellen Android SDK ist, aber ich dachte, dass jemand dies möglicherweise implementieren konnte. Jede Hilfe wird sehr geschätzt.
Aktualisieren
Ich habe BroadcastReceiver
der AndroidManifest.xml
Datei ein hinzugefügt , um MMS-Nachrichten zu empfangen
<receiver android:name="com.sendit.receivers.MMSReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
In der MMSReceiver-Klasse kann die onReceive()
Methode nur die Telefonnummer abrufen, von der die Nachricht gesendet wurde. Wie können Sie andere wichtige Dinge aus einer MMS abrufen, z. B. den Dateipfad zum Medienanhang (Bild / Audio / Video) oder den Text in der MMS?
MMSReceiver.java
public class MMSReceiver extends BroadcastReceiver {
private final String DEBUG_TAG = getClass().getSimpleName().toString();
private static final String ACTION_MMS_RECEIVED = "android.provider.Telephony.WAP_PUSH_RECEIVED";
private static final String MMS_DATA_TYPE = "application/vnd.wap.mms-message";
// Retrieve MMS
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String type = intent.getType();
if(action.equals(ACTION_MMS_RECEIVED) && type.equals(MMS_DATA_TYPE)){
Bundle bundle = intent.getExtras();
Log.d(DEBUG_TAG, "bundle " + bundle);
SmsMessage[] msgs = null;
String str = "";
int contactId = -1;
String address;
if (bundle != null) {
byte[] buffer = bundle.getByteArray("data");
Log.d(DEBUG_TAG, "buffer " + buffer);
String incomingNumber = new String(buffer);
int indx = incomingNumber.indexOf("/TYPE");
if(indx>0 && (indx-15)>0){
int newIndx = indx - 15;
incomingNumber = incomingNumber.substring(newIndx, indx);
indx = incomingNumber.indexOf("+");
if(indx>0){
incomingNumber = incomingNumber.substring(indx);
Log.d(DEBUG_TAG, "Mobile Number: " + incomingNumber);
}
}
int transactionId = bundle.getInt("transactionId");
Log.d(DEBUG_TAG, "transactionId " + transactionId);
int pduType = bundle.getInt("pduType");
Log.d(DEBUG_TAG, "pduType " + pduType);
byte[] buffer2 = bundle.getByteArray("header");
String header = new String(buffer2);
Log.d(DEBUG_TAG, "header " + header);
if(contactId != -1){
showNotification(contactId, str);
}
// ---send a broadcast intent to update the MMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("MMS_RECEIVED_ACTION");
broadcastIntent.putExtra("mms", str);
context.sendBroadcast(broadcastIntent);
}
}
}
/**
* The notification is the icon and associated expanded entry in the status
* bar.
*/
protected void showNotification(int contactId, String message) {
//Display notification...
}
}
Laut der Dokumentation von android.provider.Telephony :
Broadcast-Aktion: Das Gerät hat eine neue textbasierte SMS-Nachricht empfangen. Die Absicht hat die folgenden zusätzlichen Werte:
pdus
- EinObject[]
vonbyte[]
s, das die PDUs enthält, aus denen die Nachricht besteht.Die zusätzlichen Werte können mit extrahiert werden.
getMessagesFromIntent(android.content.Intent)
Wenn ein BroadcastReceiver bei der Verarbeitung dieser Absicht auf einen Fehler stößt, sollte er den Ergebniscode entsprechend festlegen.@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
Broadcast-Aktion: Das Gerät hat eine neue datenbasierte SMS-Nachricht empfangen. Die Absicht hat die folgenden zusätzlichen Werte:
pdus
- EinObject[]
vonbyte[]
s, das die PDUs enthält, aus denen die Nachricht besteht.Die zusätzlichen Werte können mit getMessagesFromIntent (android.content.Intent) extrahiert werden. Wenn ein BroadcastReceiver bei der Verarbeitung dieser Absicht auf einen Fehler stößt, sollte er den Ergebniscode entsprechend festlegen.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String DATA_SMS_RECEIVED_ACTION = "android.intent.action.DATA_SMS_RECEIVED";
Broadcast-Aktion: Das Gerät hat eine neue WAP PUSH-Nachricht empfangen. Die Absicht hat die folgenden zusätzlichen Werte:
transactionId (Integer)
- Die WAP-Transaktions-ID
pduType (Integer)
- Der WAP-PDU-Typ`
header (byte[])
- Der Header der Nachricht
data (byte[])
- Die Datennutzlast der Nachricht
contentTypeParameters (HashMap<String,String>)
- Alle mit dem Inhaltstyp verknüpften Parameter (aus dem WSP-Inhaltstyp-Header dekodiert)Wenn ein BroadcastReceiver bei der Verarbeitung dieser Absicht auf einen Fehler stößt, sollte er den Ergebniscode entsprechend festlegen. Der zusätzliche Wert für contentTypeParameters ist eine Zuordnung von Inhaltsparametern, die durch ihre Namen gekennzeichnet sind. Wenn nicht zugewiesene bekannte Parameter gefunden werden, lautet der Schlüssel der Karte 'nicht zugewiesen / 0x ...', wobei '...' der Hex-Wert des nicht zugewiesenen Parameters ist. Wenn ein Parameter No-Value hat, ist der Wert in der Map null.
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WAP_PUSH_RECEIVED_ACTION = "android.provider.Telephony.WAP_PUSH_RECEIVED";
Update Nr. 2
Ich habe herausgefunden, wie Extras in einem übergeben werden PendingIntent
, um von einem empfangen zu werden BroadcastReceiver
:
Android PendingIntent-Extras, die nicht von BroadcastReceiver empfangen werden
Das Extra wird jedoch an den SendBroadcastReceiver und nicht an den SMSReceiver übergeben . Wie kann ich dem SMSReceiver ein Extra übergeben ?
Update Nr. 3
MMS empfangen
Nachdem ich mehr recherchiert hatte, sah ich einige Vorschläge zur Registrierung von a ContentObserver
. Auf diese Weise können Sie erkennen, wenn Änderungen am content://mms-sms/conversations
Inhaltsanbieter vorgenommen wurden, und so eingehende MMS erkennen. Hier ist das nächste Beispiel, um dies zum Laufen zu bringen, das ich gefunden habe: Empfangen von MMS
Es gibt jedoch eine Variable mainActivity
vom Typ ServiceController
. Wo ist die ServiceController
Klasse implementiert? Gibt es noch andere Implementierungen eines registrierten ContentObserver
?
MMS senden
Beim Senden von MMS bin ich auf folgendes Beispiel gestoßen : MMS senden
Das Problem ist, dass ich versucht habe, diesen Code auf meinem Nexus 4 unter Android v4.2.2 auszuführen, und ich erhalte folgende Fehlermeldung:
java.lang.SecurityException: No permission to write APN settings: Neither user 10099 nor current process has android.permission.WRITE_APN_SETTINGS.
Der Fehler wird ausgelöst, nachdem der Carriers
ContentProvider in der getMMSApns()
Methode der APNHelper
Klasse abgefragt wurde .
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);
Anscheinend können Sie APNs in Android 4.2 nicht lesen
Was ist die Alternative für alle Anwendungen, die mobile Daten zum Ausführen von Vorgängen verwenden (z. B. das Senden von MMS) und die im Gerät vorhandene Standard-APN-Einstellung nicht kennen?
Update Nr. 4
MMS senden
Ich habe versucht, diesem Beispiel zu folgen: MMS senden
Wie @Sam in seiner Antwort vorgeschlagen hat:
You have to add jsoup to the build path, the jar to the build path and import com.droidprism.*; To do that in android, add the jars to the libs directory first, then configure the project build path to use the jars already in the libs directory, then on the build path config click order and export and check the boxes of the jars and move jsoup and droidprism jar to the top of the build order.
Jetzt erhalte ich keine SecurityException-Fehler mehr. Ich teste jetzt auf einem Nexus 5 auf Android KitKat. Nachdem ich den Beispielcode ausgeführt habe, erhalte ich nach dem Aufruf von einen 200-Antwortcode
MMResponse mmResponse = sender.send(out, isProxySet, MMSProxy, MMSPort);
Ich habe mich jedoch bei der Person erkundigt, an die ich die MMS senden wollte. Und sie sagten, sie hätten die MMS nie erhalten.