For the longest time, I’ve been wanting to write a SMS app for Android. The issue originally (and still is unfortunately) was that if you’re running a device that has a version of Android less than KitKat (4.4.x), a programmer doesn’t have access to native public-facing APIs to get access to these Content Providers. Instead you have to rely on the Reflection APIs to poke around for them and, if they’re there, use them that way. It might not seem like it at first but Reflection can be a bit heavyweight on more resource-constrained devices (which can potentially toss ANRs or even cost battery cycles) and also makes for some really nasty looking code. I’ve worked on several projects where Reflection was the order of the day (especially for things like accessing Enterprise Configurations in WifiManager) but unless I really had no other choice, I tried to stay away from the Reflection solution as much as possible. Even going to the lengths of not writing this SMS app I wanted to do for so long because there wasn’t a public API for it. Enter KitKat with these packages and now I’m going to town.
Putting aside the fact that Google likes to arbitrarily break your code with new upstream versions, the package that contains the contract classes for these Content Providers, android.providers.Telephony, is actually quite solid. Unless they go ape-shit on this package like they did with ContactsContract (which is an absolute fucking nightmare to work with), we should be okay for the time being.
I’ll save the technical discussion for another post (or even a video) but what I wanted to do here was showcase the current state of the build that I have for the SMS app. Honestly I’ve spent more time trying to figure out the nuances of the contracts and how to use them and fucking around with 9-Patch than anything else (9-Patch is cool technically but why can’t someone at Google make decent documentation?) Additionally, I wanted to provide a tentative roadmap for where this is going.
Here’s a screen capture of the home screen which will display what I refer to as the “Conversation Stubs.” No, those aren’t native constructs in Android, it’s a custom object that I’ve built for this app. The goal here was simple – after doing all the magic necessary to sort the messages to have them make sense, grab the most recent one and from it derive the contact’s display name and a 45-character snippet of the message body. If the snippet length equals 45-characters, an ellipsis is appended to it to indicate that there’s more to the message than what’s visible. What’s missing here is an indication that the message was sent from you to the intended recipient (coming in the next nightly build). By the way, I swear I didn’t plan the colour of the ActionBar to match that of my site. 😉
Pressing on one of the Conversation Stubs will bring you to another screen which will display the entire Conversation Thread.
As with Conversation Stub, a Conversation Thread is not a native construct to Android. Now if you’ve done a little digging into the package yourself, you might be thinking why not just use the Conversation Contract? I’ll do more on that in the technical discussion. Although there are no clear visual cues as to who said what, messages that have been sent from you to the recipient are on the right side and messages from the recipient to you are on the left. Each message is time-stamped currently using 24-hour format (this will be customisable in a later build). The thread recipient’s display name occupies the ActionBar in the top-left. The list of messages is sorted in descending order from the top and will automatically start from the bottom when opened which will display the most recent messages. Right now, there’s not much else here other than what you see.
The last point of interest here is the slowly building Preferences. One of my targets here is to have a decently high level of customisation while still retaining the overall look-and-feel of the app that I want. The bottom option is the more interesting one right now. As I mentioned before, KitKat will allow a user to specify an app to be the dedicated Messaging app. Of course I want the user to be able to choose this one as the default if they wish to do so. Pressing this brings up a dialogue that will allow you to choose the default app.
Overall, the goal here is quite simple. I prefer as vanilla of an experience on my Android devices and I like the Google Play Services and default apps but I have a serious beef with Hangouts. It just feels too clunky and I wanted something a little more back-to-basics. The current build cannot actually compose or send SMS yet (coming in two builds) nor can it determine or store draft messages (coming in a build after the previously mentioned one). MMS is also not yet handled but is coming shortly. I do not want to do anything fancy like integrate with Google Accounts like Hangouts does. I want this to be a pure unadulterated SMS/MMS experience. Nothing more.
Some tentative features that I have in mind though are sticky messages, cherry-pick deletion, hidden threads, export a conversation thread to a file (I’ve actually had a lot of interest in this from some clients for legal reasons) or print a conversation thread directly to a printer (relies on Android Print Services) or email a conversation thread to an email address, bulk messaging (one-to-many) and group messaging (many-to-many).
I’ll do a technical discussion on how to use the SMS Contracts and all of the nuances that I’ve discovered with them soon. Either way, I’m looking to have a first version published by the end of the month.