KitKat SMS and MMS supports

Written by: on November 15

Now this may be a bit confusing, since there are messaging apps all over the play store. So what’s different for the users and developers of these apps?

On the user side, in Android 4.4 users can now select one default messaging app. The default messaging is the only app that will be able to write and update messages to the SMS ContentProvider.

There is an excellent blog post here that goes over how to make your app the default and how to check if your app is the current default. The majority of the requirements involve the ability to respond to several actions and receive certain broadcast. What it fails to explain, however, is what you need to do once you’re the default, or your abilities if you’re not.

All of the SMS/ MMS messages stored on the device are available via ContentProviders. The big change in KitKat is how one gains access to the correct Uris and column names. In KitKat, one can venture into android.provider.Telephony. In this class are constants for any tables, columns, etc. We see a similar organization pattern as in other provider classes like MediaStore, Contacts, and CalendarContacts.

The Telephony class has always been a part of the Android. It is possible to use the api, but certain IDEs will prevent compilation for this violation. The other option is to find the constants’ values from Android references and use hard coded strings. Both of these options carry a certain risk, as there is no promise from Google that the hidden API is being tested for compatibility, etc.

If you have the android.permission.READ_SMS permission, URIs, and column names, you can simply query a ContentResolver in and get a Cursor back to read the data saved:

String[] select = new String[] {Telephony.Sms.Inbox.ADDRESS, Telephony.Sms.Inbox.BODY,
        Telephony.Sms.Inbox.DATE};
Cursor smsCursor = getContentResolver().query(
        Telephony.Sms.Inbox.CONTENT_URI,
        select, // Columns to select
        whereClause, // Clause to filter results
        whereArgs, // Arguments for the whereClause
        null); // Sort order

This can be done regardless of whether your app is the default or not.

To send a text message (provided you have the android.permission.SEND_SMS permission), you simply make a call to one of SmsManager‘s functions to send whichever kind of message you would like. For example, to send a text SMS,

SmsManager.getDefault().sendTextMessage(
        "+13038675309", // address 
        null, // Service Center address (null uses default)
        "Hello! How're you?", // message content
        null, // intent to be called on message sent (if not null)
        null); // intent to be called on message delivered (if not null)

If your application is not selected as the default SMS app on KitKat, the above will also write the text to the SMS content provider automatically. However, if you are pre-KitKat, or you are the default SMS app on a KitKat device, you are responsible for writing the message to the ContentProvider. Once you have the android.permission.WRITE_SMS permission, this can be done as,

ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, phoneNumber);
values.put(Telephony.Sms.BODY, message);
getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);

If you’re the default app or pre-KitKat, you can also update or delete messages via the content provider. If your app is not the default app and you attempt to write directly to the ContentProvider, it will fail silently, so make sure you’re the default often!

This piece is the fifth of eight in our KitKat Developer’s Guide. Check back later this week for new updates or follow us on twitter.

Joshua Lamson

Joshua Lamson is a Software Engineer at Double Encore, specializing in Android Development. Joshua is a graduate of the Colorado School of Mines and has an affinity for rubik's cubes.

Article


Add your voice to the discussion: