[LIBRARY] Android SMS and MMS library

Search This thread

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Hey guys, I put together a library to help anyone out there who is making an sms app after all my experience with Sliding Messaging and trying to get everything to work... I dug through way too much source code so hopefully this will save some others the trouble! Apologize if this isn't in the right spot mods!

Android SMS/MMS/Google Voice Sending Library

These are the APIs that Google has so far left out of the Android echosystem for easily sending any type of message without digging through source code and what not.

This library is still in BETA and has a long way to go... APIs may not be final and things will most likely change.

If you've got a better way to do things, send me a pull request! The library was created specifically for Sliding Messaging Pro and some things work the way they do specifically for that app.

-------------------------------------------

Library Overview

Sending messages is very easy to do.

First, create a settings object with all of your required information for what you want to do. If you don't set something, then it will just be set to a default and that feature may not work. For example, if you need MMS, set the MMSC, proxy, and port, or else you will get an error every time.

Code:
Settings sendSettings = new Settings();

sendSettings.setMmsc("http://mmsc.cingular.com");
sendSettings.setProxy("66.209.11.33");
sendSettings.setPort("80");
sendSettings.setGroup(true);
sendSettings.setWifiMmsFix(true);
sendSettings.setPreferVoice(false);
sendSettings.setDeliveryReports(false);
sendSettings.setSplit(false);
sendSettings.setSplitCounter(false);
sendSettings.setStripUnicode(false);
sendSettings.setSignature("");
sendSettings.setSendLongAsMms(true);
sendSettings.setSendLongAsMmsAfter(3);
sendSettings.setAccount("jklinker1@gmail.com");
sendSettings.setRnrSe(null);

- MMSC - the URL of your mms provider, found on your phone's APN settings page
- Proxy - more mms information that needs to be set for more providers to send
- Port - again, more mms stuff
- Group - whether you want to send message to multiple senders as an MMS group message or separate SMS/Voice messages
- WiFi MMS Fix - will disable wifi to send the message, only way I've found to do it, so if you can find the problem, submit a pull request :)
- Prefer Voice - send through Google Voice instead of SMS
- Delivery Reports - request reports for when SMS has been delivered
- Split - splits SMS messages when sent if they are longer than 160 characters
- Split Counter - attaches a split counter to message, ex. (1/3) in front of each message
- Strip Unicode - converts Unicode characters to GSM compatible characters
- Signature - signature to attach at the end of messages
- Send Long as MMS - when a message is a certain length, it is sent as MMS instead of SMS
- Send Long as MMS After - length to convert the long SMS into an MMS
- Account - this is the email address of the account that you want to send google voice messages from
- RnrSe - this is a weird token that google requires to send the message, nullifying it will make the library find the token every time, I'll hit later how to save the token and save your users some data down below in the Google Voice section.

Next, attach that settings object to the sender

Code:
Transaction sendTransaction = new Transaction(mContext, sendSettings);

Now, create the Message you want to send

Code:
Message mMessage = new Message(textToSend, addressToSendTo);
mMessage.setImage(mBitmap);

And then all you have to do is send the message

Code:
sendTransaction.sendNewMessage(message, threadId)

Note: threadId can be nullified, but this sometimes results in a new thread being created instead of the message being added to an existing thread

That's it, you're done sending :)

You'll also need to register a few receivers for when the messages have been sent and for delivery reports to mark them as read... In your manifest, add these lines:

Code:
<receiver android:name="com.klinker.android.send_message.SentReceiver" >
    <intent-filter>
        <action android:name="com.klinker.android.send_message.SMS_SENT" />
    </intent-filter> 
</receiver>

<receiver android:name="com.klinker.android.send_message.DeliveredReceiver" >
    <intent-filter>
                <action android:name="com.klinker.android.send_message.SMS_DELIVERED" />
    </intent-filter> 
</receiver>

Lastly, you'll need to include permissions in your manifest depending on what you want to do. Here are all of them:

Code:
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.provider.Telephony.SMS_RECEIVED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Google Voice Overview

To be able to send Google Voice messages, all you really need to do is add the final 3 permissions above and get the address of the Account that you want to send through.

To get a list of accounts available on the device, you can use the following:

Code:
ArrayList<Account> accounts = new ArrayList<Account>();
for (Account account : AccountManager.get(context).getAccountsByType("com.google")) {
    accounts.add(account);
}

Display those in a list and let the user choose which one they want to use and save that choice to your SharedPreferences.

Next, when you are configuring your send settings, you should register a receiver that listens for the action "com.klinker.android.send_message.RNRSE" like so:

Code:
if (sendSettings.getAccount() != null && sendSettings.getRnrSe() == null) {
    BroadcastReceiver receiver = new BroadcastReceiver() {
        [user=439709]@override[/user]
        public void onReceive(Context context, Intent intent) {
            sharedPrefs.edit().putString("voice_rnrse", intent.getStringExtra("_rnr_se")).commit();
        }
    };

    context.registerReceiver(receiver, new IntentFilter("com.klinker.android.send_message.RNRSE"));
}

That code will then save the RnrSe value so that I don't have to fetch it every time and waste time and data. After it is saved, just insert that value into the send settings instead and you are good to go.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

And thats it, pretty simple to do, especially for MMS! There are some problems with the library at this point, so i'm really hoping someone out there who knows more about this stuff can help me out eventually and get everything cleaned up! I feel like this should be an important part of the Android APIs, yet it is all missing so this is my go at it! :)

GitHub
 
Last edited:

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
This is my little way of giving back to xda and so I hope someone out there finds this and trys it out :)
 

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Must admit I have not looked much into mms at the moment, but what differs from the AOSP source ? The models look similar (not that I have looked in a while)

I always thought that sliding was built on top/over AOSP with additions rather than changes ?

forgive my "uninformed question" :)

Haha no, I built sliding from the ground up off of nothing, just referenced stock source when I needed to. Before I made this library, you had to download and import all kinds of internal classes not in the APIs, both from the stock app and just android source in general. This library brings all of those together so that you don't have to download hundreds of files to get the imports all sorted out (that took me days itself to do) and then it just allows you to use all those classes in a much easier way, really by only creating a message object and sending it through the transaction class.

Basically, it does everything exactly the same as what you will see from the stock source, but it encapsulates all that so third party developers have much easier access to it and can worry about more important things in their app then sifting through source code to find out how to send a stupid MMS message ha. All of the MMS source can be sooooo confusing, especially if you're just starting out like I was. :p
 
Last edited:

deanwray

Senior Member
Apr 2, 2006
1,145
427
www.deanwray.co.uk
Haha no, I built sliding from the ground up off of nothing, just referenced stock source when I needed to. Before I made this library, you had to download and import all kinds of internal classes not in the APIs, both from the stock app and just android source in general. This library brings all of those together so that you don't have to download hundreds of files to get the imports all sorted out (that took me days itself to do) and then it just allows you to use all those classes in a much easier way, really by only creating a message object and sending it through the transaction class.

Basically, it does everything exactly the same as what you will see from the stock source, but it encapsulates all that so third party developers have much easier access to it and can worry about more important things in their app then sifting through source code to find out how to send a stupid MMS message ha. All of the MMS source can be sooooo confusing, especially if you're just starting out like I was. :p

well I will def look at it when adding mms to SmartMessenger and let you know what I think :) We in the UK don't use MMS at all hardy, costs too much :)
 
  • Like
Reactions: dbjc

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Heads up to anyone who is curious, just pushed google voice support for sending to the library. it is a little tricky to figure out the account stuff, so i'll update the readme when I'm done with classes for the day at school.

EDIT: put google voice stuff in the readme, so anyone looking who wants to try should be good to go.
 
Last edited:

Marx2

Senior Member
May 6, 2006
379
15
Gliwice
Great library. Do you think your library could deal also with network messages? Allowing to send them is probably similar to sending SMS (if not exactly the same), but tricky is intercepting response
 

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Great library. Do you think your library could deal also with network messages? Allowing to send them is probably similar to sending SMS (if not exactly the same), but tricky is intercepting response

What network messages do you mean? Google voice messages are sent over the internet if that is what you are talking about?
 

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Gonna look at your shiny lib quite soon, and while I was just sat here, I decided to look at MMS/Android just to get an overview, WTF ?? They removed the ability to read APN/Addressing/Server info ? So now my obvious question... how would I get that in order use your lib ?

I take it the solution is not to ask the user to enter that info ??

Yeah, they made it really difficult to get apns in 4.0+ i think :( it sucks. For Sliding Messaging, I have list of carriers that the user can select from to get it working, and if theirs isn't on that list then they have to enter it manually. Was hoping google would change it back in 4.3 (or at least give us read but not write privileges) but they didn't.
 

deanwray

Senior Member
Apr 2, 2006
1,145
427
www.deanwray.co.uk
Yeah, they made it really difficult to get apns in 4.0+ i think :( it sucks. For Sliding Messaging, I have list of carriers that the user can select from to get it working, and if theirs isn't on that list then they have to enter it manually. Was hoping google would change it back in 4.3 (or at least give us read but not write privileges) but they didn't.

And the thinking is to protect against what ??? :) I really can't think of a reason... suppose if the device is rooted you can query the db locations (search) then read directly ?
Where did you get that list from btw ? and was there no automated way to detect carrier and only ask user if not detect/dont have settings ? I hate the thought of asking users to do this...makes my skin crawl !
 

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
And the thinking is to protect against what ??? :) I really can't think of a reason... suppose if the device is rooted you can query the db locations (search) then read directly ?
Where did you get that list from btw ? and was there no automated way to detect carrier and only ask user if not detect/dont have settings ? I hate the thought of asking users to do this...makes my skin crawl !

Exactly, I have no idea. Apns can't mess up your phone more than just making you lose an internet connection, no idea why they need to be protected. It was just a list that I made, I started with a beta period for MMS and had users email me apns that worked for them, then gave it to the general public with that list. My user base tends to be people who mostly don't mind inputting their apns manually haha, lucky me.

As for figuring out the carrier, I believe that is possible but I haven't looked into it much. I just use an initial setup wizard that asks them for carrier along with other option for them to set up off the bat.


EDIT: may want to look at this for taking car of auto detecting apns. haven't tried it yet, but I'm going to look into it when i get the chance.
 
Last edited:

dbjc

Senior Member
Nov 20, 2009
165
24
Use case

Say I have to send one simple SMS.
How am I aware of either the success or the failure of the 'SEND' operation given that I do not ask for delivery report? Any sample code to do that like the sample you give in OP?
Is it mandatory to specify MMSC URL/Proxy/Port in the sendSettings when just sending SMSes?
 

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
Say I have to send one simple SMS.
How am I aware of either the success or the failure of the 'SEND' operation given that I do not ask for delivery report? Any sample code to do that like the sample you give in OP?
Is it mandatory to specify MMSC URL/Proxy/Port in the sendSettings when just sending SMSes?

Just register the sent broadcast receiver

Code:
<receiver android:name="com.klinker.android.send_message.SentReceiver" >
    <intent-filter>
        <action android:name="com.klinker.android.send_message.SMS_SENT" />
    </intent-filter> 
</receiver>

If you are sending sms you don't have to set any of the settings if you don't want to, especially if you don't want delivery reports. It will fill everything in with default values when you create it and then you're good to send away
 
  • Like
Reactions: dbjc

klinkdawg

Senior Member
Jul 13, 2010
572
1,744
For anyone looking for MMS support from the library, it has come an extremely long ways over the past week or so and should work very well for anyone trying to use it as long as you set the APNs for the user correctly!
 

Marx2

Senior Member
May 6, 2006
379
15
Gliwice
Not sure that falls under the domain of a messaging lib

Ussd codes are messages. They can be send (similarly to SMS) and network can respond their own message.
As I understand they are named "SMS Class 0". So for example dumbphones can't save them. My sgs2 asks me if I want to save such incoming message box. They are often used to activate phone account settings, or to receive phone account balance.
There in fact is no library for ussd codes, while some code snippets can be find on stackoverflow, and they are working.
If you would like, I have one project which allow for sending and receving such messages and can share it.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 8
    Hey guys, I put together a library to help anyone out there who is making an sms app after all my experience with Sliding Messaging and trying to get everything to work... I dug through way too much source code so hopefully this will save some others the trouble! Apologize if this isn't in the right spot mods!

    Android SMS/MMS/Google Voice Sending Library

    These are the APIs that Google has so far left out of the Android echosystem for easily sending any type of message without digging through source code and what not.

    This library is still in BETA and has a long way to go... APIs may not be final and things will most likely change.

    If you've got a better way to do things, send me a pull request! The library was created specifically for Sliding Messaging Pro and some things work the way they do specifically for that app.

    -------------------------------------------

    Library Overview

    Sending messages is very easy to do.

    First, create a settings object with all of your required information for what you want to do. If you don't set something, then it will just be set to a default and that feature may not work. For example, if you need MMS, set the MMSC, proxy, and port, or else you will get an error every time.

    Code:
    Settings sendSettings = new Settings();
    
    sendSettings.setMmsc("http://mmsc.cingular.com");
    sendSettings.setProxy("66.209.11.33");
    sendSettings.setPort("80");
    sendSettings.setGroup(true);
    sendSettings.setWifiMmsFix(true);
    sendSettings.setPreferVoice(false);
    sendSettings.setDeliveryReports(false);
    sendSettings.setSplit(false);
    sendSettings.setSplitCounter(false);
    sendSettings.setStripUnicode(false);
    sendSettings.setSignature("");
    sendSettings.setSendLongAsMms(true);
    sendSettings.setSendLongAsMmsAfter(3);
    sendSettings.setAccount("jklinker1@gmail.com");
    sendSettings.setRnrSe(null);

    - MMSC - the URL of your mms provider, found on your phone's APN settings page
    - Proxy - more mms information that needs to be set for more providers to send
    - Port - again, more mms stuff
    - Group - whether you want to send message to multiple senders as an MMS group message or separate SMS/Voice messages
    - WiFi MMS Fix - will disable wifi to send the message, only way I've found to do it, so if you can find the problem, submit a pull request :)
    - Prefer Voice - send through Google Voice instead of SMS
    - Delivery Reports - request reports for when SMS has been delivered
    - Split - splits SMS messages when sent if they are longer than 160 characters
    - Split Counter - attaches a split counter to message, ex. (1/3) in front of each message
    - Strip Unicode - converts Unicode characters to GSM compatible characters
    - Signature - signature to attach at the end of messages
    - Send Long as MMS - when a message is a certain length, it is sent as MMS instead of SMS
    - Send Long as MMS After - length to convert the long SMS into an MMS
    - Account - this is the email address of the account that you want to send google voice messages from
    - RnrSe - this is a weird token that google requires to send the message, nullifying it will make the library find the token every time, I'll hit later how to save the token and save your users some data down below in the Google Voice section.

    Next, attach that settings object to the sender

    Code:
    Transaction sendTransaction = new Transaction(mContext, sendSettings);

    Now, create the Message you want to send

    Code:
    Message mMessage = new Message(textToSend, addressToSendTo);
    mMessage.setImage(mBitmap);

    And then all you have to do is send the message

    Code:
    sendTransaction.sendNewMessage(message, threadId)

    Note: threadId can be nullified, but this sometimes results in a new thread being created instead of the message being added to an existing thread

    That's it, you're done sending :)

    You'll also need to register a few receivers for when the messages have been sent and for delivery reports to mark them as read... In your manifest, add these lines:

    Code:
    <receiver android:name="com.klinker.android.send_message.SentReceiver" >
        <intent-filter>
            <action android:name="com.klinker.android.send_message.SMS_SENT" />
        </intent-filter> 
    </receiver>
    
    <receiver android:name="com.klinker.android.send_message.DeliveredReceiver" >
        <intent-filter>
                    <action android:name="com.klinker.android.send_message.SMS_DELIVERED" />
        </intent-filter> 
    </receiver>

    Lastly, you'll need to include permissions in your manifest depending on what you want to do. Here are all of them:

    Code:
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_MMS"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.provider.Telephony.SMS_RECEIVED" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    Google Voice Overview

    To be able to send Google Voice messages, all you really need to do is add the final 3 permissions above and get the address of the Account that you want to send through.

    To get a list of accounts available on the device, you can use the following:

    Code:
    ArrayList<Account> accounts = new ArrayList<Account>();
    for (Account account : AccountManager.get(context).getAccountsByType("com.google")) {
        accounts.add(account);
    }

    Display those in a list and let the user choose which one they want to use and save that choice to your SharedPreferences.

    Next, when you are configuring your send settings, you should register a receiver that listens for the action "com.klinker.android.send_message.RNRSE" like so:

    Code:
    if (sendSettings.getAccount() != null && sendSettings.getRnrSe() == null) {
        BroadcastReceiver receiver = new BroadcastReceiver() {
            [user=439709]@override[/user]
            public void onReceive(Context context, Intent intent) {
                sharedPrefs.edit().putString("voice_rnrse", intent.getStringExtra("_rnr_se")).commit();
            }
        };
    
        context.registerReceiver(receiver, new IntentFilter("com.klinker.android.send_message.RNRSE"));
    }

    That code will then save the RnrSe value so that I don't have to fetch it every time and waste time and data. After it is saved, just insert that value into the send settings instead and you are good to go.

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    And thats it, pretty simple to do, especially for MMS! There are some problems with the library at this point, so i'm really hoping someone out there who knows more about this stuff can help me out eventually and get everything cleaned up! I feel like this should be an important part of the Android APIs, yet it is all missing so this is my go at it! :)

    GitHub
    1
    Have you got a link to your library?

    Great job. :good:

    Haha oops, that might be helpful ;) https://github.com/klinker41/android-smsmms
    1
    Haha no, I built sliding from the ground up off of nothing, just referenced stock source when I needed to. Before I made this library, you had to download and import all kinds of internal classes not in the APIs, both from the stock app and just android source in general. This library brings all of those together so that you don't have to download hundreds of files to get the imports all sorted out (that took me days itself to do) and then it just allows you to use all those classes in a much easier way, really by only creating a message object and sending it through the transaction class.

    Basically, it does everything exactly the same as what you will see from the stock source, but it encapsulates all that so third party developers have much easier access to it and can worry about more important things in their app then sifting through source code to find out how to send a stupid MMS message ha. All of the MMS source can be sooooo confusing, especially if you're just starting out like I was. :p

    well I will def look at it when adding mms to SmartMessenger and let you know what I think :) We in the UK don't use MMS at all hardy, costs too much :)
    1
    Say I have to send one simple SMS.
    How am I aware of either the success or the failure of the 'SEND' operation given that I do not ask for delivery report? Any sample code to do that like the sample you give in OP?
    Is it mandatory to specify MMSC URL/Proxy/Port in the sendSettings when just sending SMSes?

    Just register the sent broadcast receiver

    Code:
    <receiver android:name="com.klinker.android.send_message.SentReceiver" >
        <intent-filter>
            <action android:name="com.klinker.android.send_message.SMS_SENT" />
        </intent-filter> 
    </receiver>

    If you are sending sms you don't have to set any of the settings if you don't want to, especially if you don't want delivery reports. It will fill everything in with default values when you create it and then you're good to send away