Hello guys,
It’s been a long time, but I am back with yet another Android packed problem I was recently solving!
I was implementing an SMS gateway for Android, which sound like a quite solved task, but apparently is not!
I tried the first Google Play results but couldn’t get any of the listed apps work.
Some of the apps required setting them to default sms app which made messenger not work, and for untold reasons I had to run this on my primary phone!
There’s an open market, go ahead and make one of your own, that actually works on Android 6.0!
So the problem sounds simple, I’ll create a BroadcastReceiver which listens for a action SMS_RECEIVED, which as the name says, listens for sms receiving broadcasts.
It seems like an easy task to hook into the sms system, unfortunately there have been couple of bigger changes after the original API has been updated(or at least all the documentation for it?) and that code, which blindly listens for SMS_RECEIVED with the RECEIVE_SMS permission, works on device thats running Android version lower than kitkat, which the device I originally tested on was.
Unfortunately when the code was ready for its prime time and I uploaded it on my primary phone(Nexus 6P <3) and as I received a test message, nothing happened, I was stumbled, but after a quick google I remember, the phone of mine had the new fancy runtime permissions, easy beasy, right?
After setting the sms reading permission, or whatever it is called on the runtime permission management UI and fired another test message, but as I look into the screen of my trusty Nexus 6P, still nothing appeared, I was getting frustrated!
The testing was getting quite costy, what are those messages here, 8 cents a pop? I have to apply for a loan before the app is finished, I guess..
Then I kept on googling and actually one of the SMS Gateway app creators have blogged about a similar problem on post kitkat devices, and I was getting hopeful, but after declaring the BROADCAST_SMS permission in my manifest, which document for reads as:
Allows an application to broadcast an SMS receipt notification.
Not for use by third-party applications.
This doesn’t sound right, but can a blog post be wrong, mine isn’t so lets try!
Unfortunately it was still no help, no broadcasts were received by my app whatsoever! Not to say that this permission could solve some kitkat problem, I don’t know, I haven’t tried, but lets figure out whats wrong with my receiver!
Time to look into some working apps! I am actually using one of those sms receive listening apps, namely ‘Fonecta Caller‘, probably not familiar for my foreign readers, but its basically a call ID app which shows the caller name if you don’t have it on the address book, so whats better way to find out what I am doing wrong than to decompile one of these apps, right?
I looked into the sources of Fonecta Callers manifest and source but couldn’t find anything exciting, and I was stumbled, but then it hit me, maybe there’s some hidden ‘protection feature’ to annoy us, developers, that one needs to declare an activity in order to be able to receive sms broadcasts, it surely would be weird, but that’s really the only difference between mine and the caller apps source, the receiver wise, and to my surprise it worked!
And after all this hard work, spending couple of hours working on the stupidest problem, I decided to create minimal implementation with a working broadcast receiver of which requirements I am listing below
- RECEIVE_SMS permission
- Launcher activity with action ACTION_MAIN and category LAUNCHER (other combinations might work, I am not sure which is the exact requirement, but without a home visible activity I couldn’t receive any broadcasts)
- As of Android 6.0 a runtime permission request for RECEIVE_SMS or manually setting the permission on
TLDR:
To receive SMS_RECEIVED broadcasts you must have an activity with action ACTION_MAIN and category LAUNCHER combination, RECEIVE_SMS permission declared in manifest and a runtime permission if you’re running Android 6.0 or newer!
Final result: (logcat)
D/SMSReceiver: onReceive