wake-up-neo.com

Senden und Empfangen SMS und MMS in Android (pre Kit Kat Android 4.4 )

Ich habe herausgefunden, wie man SMS) Nachrichten sendet und empfängt. Um SMS) Nachrichten zu senden, musste ich die sendTextMessage() und sendMultipartTextMessage() Methoden der Klasse SmsManager. Um SMS) Nachrichten zu empfangen, musste ich einen Empfänger in der Datei AndroidMainfest.xml registrieren und dann überschreiben Die onReceive() -Methode von BroadcastReceiver. Ich habe Beispiele unten aufgenommen.

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 auf ähnliche Weise MMS) - Nachrichten senden und empfangen können. Nach einigen Recherchen geben viele Beispiele in Blogs einfach ein Intent an das native Messaging weiter Ich versuche, eine MMS zu senden, ohne meine Anwendung zu verlassen. Es scheint keine Standardmethode für das Senden und Empfangen von MMS zu geben. Hat dies jemand zum Laufen gebracht?

Ich bin mir auch bewusst, dass der SMS/MMS ContentProvider kein Teil des offiziellen Android= SDK ist, aber ich dachte, jemand könnte dies implementieren. Jede Hilfe wird sehr geschätzt.

Aktualisieren

Ich habe der AndroidManifest.xml - Datei ein BroadcastReceiver 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 phoneNumber abrufen, von der die Nachricht gesendet wurde. Wie können Sie andere wichtige Dinge aus einer MMS) wie den Dateipfad zum Medienanhang (Bild/Audio/Video) oder den Text in der MMS abrufen?

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 Dokumentation von Android.provider.Telephony :

Broadcast-Aktion: Eine neue textbasierte SMS wurde vom Gerät empfangen. Die Absicht hat die folgenden zusätzlichen Werte:

pdus - Ein Object[] von byte[], der 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 einstellen.

 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
 public static final String SMS_RECEIVED_ACTION = "Android.provider.Telephony.SMS_RECEIVED";

Broadcast-Aktion: Eine neue datenbasierte SMS Nachricht wurde vom Gerät empfangen. Die Absicht hat die folgenden zusätzlichen Werte:

pdus - Ein Object[] von byte[], der 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 einstellen.

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String DATA_SMS_RECEIVED_ACTION = "Android.intent.action.DATA_SMS_RECEIVED";

Broadcast-Aktion: Eine neue WAP-Push-Nachricht wurde vom Gerät 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 Parameter, die dem Inhaltstyp zugeordnet sind (dekodiert aus dem WSP-Inhaltstyp-Header)

Wenn ein BroadcastReceiver bei der Verarbeitung dieser Absicht auf einen Fehler stößt, sollte er den Ergebniscode entsprechend einstellen. Der zusätzliche Wert contentTypeParameters ist eine Zuordnung von Inhaltsparametern, die durch ihre Namen gekennzeichnet sind. Wenn nicht zugewiesene bekannte Parameter angetroffen werden, lautet der Schlüssel der Zuordnung "nicht zugewiesen/0x ...", wobei "..." der hexadezimale Wert des nicht zugewiesenen Parameters ist. Wenn ein Parameter keinen Wert hat, ist der Wert in der Zuordnung 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 PendingIntent übergeben werden, um von einem BroadcastReceiver empfangen zu werden: Android PendingIntent-Extras, nicht von BroadcastReceiver empfangen

Das Extra wird jedoch an den SendBroadcastReceiver übergeben, nicht an den SMSReceiver. Wie kann ich dem SMSReceiver ein Extra übergeben?

Update Nr. 3

Empfangen von MMS

Nachdem ich mehr recherchiert hatte, sah ich einige Vorschläge für die Registrierung eines ContentObserver. Auf diese Weise können Sie feststellen, ob Änderungen am Inhaltsanbieter content://mms-sms/conversations Vorgenommen wurden, sodass Sie eingehende MMS erkennen können. Hier ist das nächste Beispiel, um dies zum Laufen zu bringen, das ich gefunden habe: Receiving MMS

Es gibt jedoch eine Variable mainActivity vom Typ ServiceController. Wo ist die Klasse ServiceController implementiert? Gibt es andere Implementierungen eines registrierten ContentObserver?

MMS senden

Beim Versenden von MMS bin ich auf folgendes Beispiel gestoßen: MMS senden

Das Problem ist, dass ich versucht habe, diesen Code auf meinem Nexus 4 auszuführen, das auf Android v4.2.2 ist, und ich diesen Fehler erhalte:

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 ContentProvider Carriers in der Methode getMMSApns() der Klasse APNHelper abgefragt wurde.

final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), null, null, null, null);

Anscheinend kannst du nicht lies APNs in Android 4.2

Was ist die Alternative für alle Anwendungen, die mobile Daten zum Ausführen von Vorgängen (z. B. zum Senden von MMS) verwenden und die im Gerät vorhandene Standard-APN-Einstellung nicht kennen?

Update Nr. 4

MMS senden

Ich habe folgendes Beispiel ausprobiert: 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= gesendet habe, und sie sagten, sie hätten die MMS nie erhalten.

131
toobsco42

Ich hatte genau das gleiche Problem, das Sie oben beschrieben haben (Galaxy Nexus auf t-mobile USA), weil mobile Daten deaktiviert sind.

In Jelly Bean ist dies: Einstellungen> Datennutzung> mobile Daten

Beachten Sie, dass ich mobile Daten VOR dem Senden einer MMS OR Empfangen einer. Wenn ich eine MMS = Bei deaktivierten mobilen Daten erhalte ich eine Benachrichtigung über eine neue Nachricht und erhalte die Nachricht mit einem Download-Button. Wenn ich jedoch noch keine mobilen Daten habe, wird der eingehende MMS Anhang wird nicht empfangen, auch wenn ich ihn nach dem Empfang der Nachricht einschalte.

Aus irgendeinem Grund müssen Sie, wenn Ihr Telefonanbieter Ihnen das Senden und Empfangen von MMS ermöglicht, die mobilen Daten aktiviert haben, auch wenn Sie Wifi verwenden, wenn die mobilen Daten aktiviert sind Sie können MMS empfangen und senden, auch wenn Wifi auf Ihrem Gerät als Internetverbindung angezeigt wird.

Es ist ein echtes Problem, denn wenn Sie es nicht aktiviert haben, kann die Nachricht selbst beim Einschalten von Mobile Data sehr hängen bleiben und möglicherweise einen Neustart des Geräts erfordern.

15
Manan Sharma

Es gibt keine offizielle API-Unterstützung, was bedeutet, dass sie nicht für die Öffentlichkeit dokumentiert ist und sich die Bibliotheken jederzeit ändern können. Mir ist klar, dass Sie die Anwendung nicht verlassen möchten, aber hier ist, wie Sie dies mit der Absicht tun, dass sich andere fragen.

public void sendData(int num){
    String fileString = "..."; //put the location of the file here
    Intent mmsIntent = new Intent(Intent.ACTION_SEND);
    mmsIntent.putExtra("sms_body", "text");
    mmsIntent.putExtra("address", num);
    mmsIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(fileString)));
    mmsIntent.setType("image/jpeg");
    startActivity(Intent.createChooser(mmsIntent, "Send"));

}

Ich habe nicht vollständig herausgefunden, wie man die Zustellung der Nachricht verfolgt, aber dies sollte sie verschicken.

Sie können auf die gleiche Weise wie per SMS über den Erhalt von MMS informiert werden. Der Intent-Filter auf dem Empfänger sollte so aussehen.

<intent-filter>
    <action Android:name="Android.provider.Telephony.WAP_Push_RECEIVED" />
    <data Android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
7
user1959417

Um eine mms für Android 4.0 api 14 oder höher ohne Erlaubnis zum Schreiben von apn-Einstellungen zu senden, können Sie diese Bibliothek verwenden: mnc- und mcc-Codes von Android abrufen und dann anrufen

Carrier c = Carrier.getCarrier(mcc, mnc);
if (c != null) {
    APN a = c.getAPN();
    if (a != null) {
        String mmsc = a.mmsc;
        String mmsproxy = a.proxy; //"" if none
        int mmsport = a.port; //0 if none
    }
}

Fügen Sie dazu Jsoup und das Droid-Prisma-Glas zum Erstellungspfad hinzu und importieren Sie com.droidprism. *;

4
Sam Adamsh

Ich glaube nicht, dass es eine SDK-Unterstützung für das Senden von mms in Android gibt. Schau hier Zumindest habe ich noch nicht gefunden. Aber ein Typ behauptete, es zu haben. Schauen Sie sich diesen Beitrag an.

Senden MMS von meiner Anwendung in Android

3