Detecting MMS messages on Android
Asked Answered
D

4

10

I was searching through the internet for this topic and couldn't find any satisfying answer... I'm trying to detect MMS messages (incoming at least for start). And I've decided to go through the way of detecting changes in the contents. I've downloaded Android codes and made sure that I'm using correct content provider: "content://mms" (in android.provider.Telephony.Mms class) and I'm using all needed permissions (from Mms application) I've come up with a sample application that detects incoming MMS messages, how ever it does not detect them. here is the application:

package com.kolomiyets.MMStesting;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class MMStesting extends Activity {

public static final String MMSMON_RECEIVED_MMS = "MMStesting.intent.action.MMSMON_RECEIVED_MMS";

Uri mmsInURI = Uri.parse("content://mms");

ContentObserver mmsObserver = new ContentObserver(null) {
    @Override
    public void onChange(boolean selfChange) {

        Thread mmsNotify = new Thread(){
            @Override
            public void run() {
                Intent mIntent = new Intent(MMSMON_RECEIVED_SMS);
                sendBroadcast(mIntent);
                super.run();
            }
        };
        mmsNotify.start();
        super.onChange(selfChange);
    }
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    BroadcastReceiver mmsMonitorBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            TextView log = (TextView)findViewById(R.id.mms_log);
            log.append("\n MMS Received;");
        }
    };

    IntentFilter mIntentFilter = new IntentFilter();
    mIntentFilter.addAction(MMSMON_RECEIVED_MMS);

    registerReceiver(mmsMonitorBroadcastReceiver, mIntentFilter);

    getApplicationContext().getContentResolver().registerContentObserver(mmsInURI, true, mmsObserver);
    getApplicationContext().getContentResolver().notifyChange(mmsInURI, mmsObserver);


}

@Override
protected void onDestroy() {
    getApplicationContext().getContentResolver().unregisterContentObserver(mmsObserver);
    super.onDestroy();
}
}

and the manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.kolomiyets.MMStesting"
  android:versionCode="1"
  android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INSTALL_DRM"/>


<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".MMStesting"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>

So far I tried "content://mms-sms" and application starts detecting something endlessly after device receives MMS message. There is no indication about new MMS in the status bar(as it should be), however the message appears in the incoming messages o_O...

Also I tried putting "content://sms" and everything works as it supposed to (detection of incomming and outgoing SMSs and even MMSs o_O)

Do I misunderstand something? Is there a way to correct my app so it would detect changes in "content://mms"? If it does not work in this app, than I won't be able to use this content in my database requests? If I'll detect changes with "content://sms" how can I distinguish between SMS and MMS? (I'd like to get what is in MMS as well). Or may be the best idea is just taking all those classes from android sources and trying to modify them the way I want? ...But I would'n like to do it)))

Here is a

grepcode.com: Telephony class that contains MMS calass (also this site is convenient for browsing android source code)

This information somewhat describes, how to retrieve information from MMS messages that are in the database. However, I still can't figure out the way to detect ingoing and outgoing MMS messages.

It looks like to me that I have to to monitor "content://sms" in order to detect MMSs (since "content://sms" reacts on incoming MMSs and "content://mms" does not), and than work with "content://mms" over Cursor and ContentResolver.

But I'm not sure this is a right way... Also I don't understand what actually Part (or PduPart) represents... will i get a complete picture by retrieving Part from MMS or it will be a part of the picture? And is there any difference between "content://mms//part" and "content://mms/part/"?

Here is also an interesting moment with WAP Push Messages. As far as I've understood these represent some kind of some special SMS messages with hyper links, and they are also used to transfer configurations from mobile provider to client's phone. This class:

code.google.com: MmsReceiver.java is supposed to detect MMS messages with help of WAP Push Massages.

I really can't make sense out of it. How?

Deucalion answered 16/3, 2011 at 18:15 Comment(1)
I am doing something similar HERE!!! #14453308Expectation
S
8

Detecting an incomming MMS message is easy, just put in broadcast receiver monitoring WAP_PUSH_RECIEVED events, as in...

<receiver android:name=".PushReceiver">
  <intent-filter>
    <action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
    <data android:mimeType="application/vnd.wap.mms-message" />
  </intent-filter>
</receiver>

Making sense out of what you get is a lot harder. I managed to decode everything I wanted from the WAP_PUSH_RECEIVED intent by cloning the PDU parsing code from the Mms app.

Retrieving the actual contents from the part files is what I am still working on, which is how I found this topic in the first place.

Subequatorial answered 16/6, 2011 at 18:42 Comment(5)
the problem with this is that the mms is not present in the contentprovider when you receive the broadcastCounterscarp
What does your PushReceiver class look like? Please post relevant code.Expectation
@Subequatorial I tried this solution but still cannot receive the broadcast. What could possibly be the problem?Tahiti
I am doing something similar HERE!!! #21748709Expectation
what if we just want the phone number of the sender? not the actual image. Is there an easy way to do that?Demicanton
D
5

Here are some helpful links that I've found:

anddev.org: Where can I find information about sending/receiving MMS?

anddev.org: Acces to the MMS part file content

Deucalion answered 21/3, 2011 at 20:29 Comment(2)
The first link has an example MMSMonitor Class which contains a variable mainActivity of type ServiceController. Where is the ServiceController class implemented?Expectation
Not able to access this link. Any archives?Etch
C
0

the incoming msg your ContentObserver detect is Notification type MMS, when phone receive this notification, it will download from mmsc the real MMS. So, when you detect new msg, you should filter Notification type.

Chiffonier answered 1/11, 2012 at 10:57 Comment(1)
Do you have some sample code to demonstrate what you are talking about?Expectation
K
0
final IntentFilter filterMMS = IntentFilter.create("android.provider.Telephony.WAP_PUSH_RECEIVED", "application/vnd.wap.mms-message");
filterMMS.setPriority(Integer.MAX_VALUE);
registerReceiver(smsreceiver, filterMMS);
Kedron answered 31/7, 2013 at 2:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.