Sending and Receiving Sms and Mms in Android (Pre Kit Kat Android 4.4)

Android KitKat 4.4 Hangouts cannot handle Sending SMS intent

I attached a code that solve the problem by doing the following:

  • Check the OS version
  • In case that older version (prior to KitKat), use the old method
  • If new API, check the default sms package. if there is any, set it as the package, otherwise, let the user choose the sharing app.

Here is the code:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //At least KitKat
{
String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(activity); //Need to change the build to API 19

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, smsText);

if (defaultSmsPackageName != null)//Can be null in case that there is no default, then the user would be able to choose any app that support this intent.
{
sendIntent.setPackage(defaultSmsPackageName);
}
activity.startActivity(sendIntent);

}
else //For early versions, do what worked for you before.
{
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setData(Uri.parse("sms:"));
sendIntent.putExtra("sms_body", smsText);
activity.startActivity(sendIntent);
}

SMS Block and Allow issue in android 4.4 (kitkat) version

The Telephony content provider (the "SMS Provider") allows apps to read and write SMS and MMS messages on the device. It includes tables for SMS and MMS messages received, drafted, sent, pending, and more.

Beginning with Android 4.4, the system settings allow users to select a "default SMS app." Once selected, only the default SMS app is able to write to the SMS Provider and only the default SMS app receives the SMS_DELIVER_ACTION broadcast when the user receives an SMS or the WAP_PUSH_DELIVER_ACTION broadcast when the user receives an MMS. The default SMS app is responsible for writing details to the SMS Provider when it receives or sends a new message.

Other apps that are not selected as the default SMS app can only read the SMS Provider, but may also be notified when a new SMS arrives by listening for the SMS_RECEIVED_ACTION broadcast, which is a non-abortable broadcast that may be delivered to multiple apps. This broadcast is intended for apps that---while not selected as the default SMS app---need to read special incoming messages such as to perform phone number verification.

For more information, read the blog post, Getting Your SMS Apps Ready for KitKat.

Sample manifest from android blog is;

<manifest>
...
<application>
<!-- BroadcastReceiver that listens for incoming SMS messages -->
<receiver android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER" />
</intent-filter>
</receiver>

<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver android:name=".MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>

<!-- Activity that allows the user to send new SMS/MMS messages -->
<activity android:name=".ComposeSmsActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>

<!-- Service that delivers messages from the phone "quick response" -->
<service android:name=".HeadlessSmsSendService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
</application>
</manifest>

Sending mms in android 4.4

Easiest way i found for sending mms is android-smsmms library found here: https://github.com/klinker41/android-smsmms

For gettings mmsc, proxy and port i used:

 final Cursor apnCursor = SqliteWrapper.query(mContext, this.mContext.getContentResolver(),
Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"), APN_PROJECTION, null, null, null);
String type = null;
if (apnCursor.moveToFirst()) {
do {
type = apnCursor.getString(3);
if(type.equals("default,supl,mms") ||
type.equals("mms")) {
mmsc = apnCursor.getString(0);
proxy = apnCursor.getString(1);
port = apnCursor.getString(2);
}while (apnCursor.moveToNext());

In if loop i am checking if APN has MMS data that i need otherwise go to next one.

Receive MMS - no default application [KITKAT]

maybe can I save mms to the SMS Provider from my app in onReceive() method and next launch native (no default) sms/mms app to display them?

This, I would imagine, is possible, but I don't think it's going to work out well in the end. To do this, your app, upon first startup, would need to get the already-set default app using Telephony.Sms.getDefaultSmsPackage(), and store this package name in order to launch it after your app's writes upon MMS receipt. This part I see no problem with.

The catch comes when the now-demoted app tries to send an MMS. Quoting the blog you've linked:

Although the system writes sent SMS messages to the SMS Provider while your app is not the default SMS app, it does not write sent MMS messages

Now, this might be acceptable, if your app could do the outgoing writes as well. The first problem I see is that, as far as I know, there is no system-wide broadcast when an MMS is sent, so your app wouldn't know it's happening, let alone have access to data not explicitly handed to it. Secondly, again quoting:

while your app is not selected as the default, it's important that you understand the limitations placed upon your app and disable features as appropriate

Assuming the platform app follows these prescribed practices, when it is no longer the default, it may very well disable its outgoing MMS functions. But, even if it doesn't, and it reverts from its direct sends to passing the request and data through an Intent to the default app, well, at this point you're handling both incoming and outgoing MMS, thus defeating the whole point of your workaround.

In the end, it's probably just easier to go ahead and make your app totally compliant.



Related Topics



Leave a reply



Submit