This is a brief tutorial about how you can really implement a SMS Broadcast Receiver in your Android application. This tutorial is going to be short and concise.
Let us dig right in and start at the very basics. I will be presenting a hypothetical scenario.
Google has really updated how one can interact with SMS in android. They have changed even the google developer policy. Applications with SMS permissions cannot be uploaded to Play Store normally. But this is beyond the scope of this article.
TECHENUM
NOTE: The tutorial here uses Kotlin
Quick Navigation
The Scenario
You are building some kind of application which needs to grab and process the content from received SMS.
Catching the SMS when it is received the device is not tricky. But how you process the raw data and to convert it to actual content can be quite tricky.
Let us see how such thing might be possible with the working code.
The SMS permission
Google has really updated how one can interact with SMS in android. They have changed even the google developer policy. Applications with SMS permissions cannot be uploaded to Play Store normally. But this is beyond the scope of this article.
You need to add the permissions below into your AndroidManifest.xml
< uses-permission android:name="android.permission.RECEIVE_SMS" />
Code language: HTML, XML (xml)
The permission above is all we need because we are only receiving the SMS.
The SMS Broadcast Receiver
Next we will need to register Broadcast Receiver so that our application will get notified each time a SMS is received.
Create a class named IncomingSmsReceiver
which will extend BroadcastReceiver
.
Don’t worry about the SmsMessageUtil
class ( technically an Object ) and other method i.e. getAnyList()
( this method does not belong to Kotlin, it’s just an extension ).
Let us first look at our broadcast receiver code. I do hope you can understand it, it’s pretty straight forward.
class IncomingSmsReceiver : BroadcastReceiver() {
val TAG = this.javaClass.simpleName
override fun onReceive(context: Context?, intent: Intent?) {
val extra = intent?.extras ?: kotlin.run {
Log.e(TAG, "There were no extras here.")
return
}
val pdus = extra.getAnyList(SmsMessageUtil.KEY_PDUS) ?: return
val sms = ArrayList<SmsMessage>()
val message =
SmsMessageUtil.getSmsMessage(pdus, extra.getString(SmsMessageUtil.KEY_FORMAT))
Log.d(TAG, "someone sent you this : $message")
}
}
Code language: Kotlin (kotlin)
The message
variable will hold the actual text message content which was received. It is also being debug logged
to the logcat
.
We are now one step closer to implementing our SMS receiver in android.
Also Read: Interface in OOP: Guide to Polymorphism and Callbacks
TECHENUM
The helper class
At this point, the code in the broadcast receiver will have some errors. Let us resolve the errors quickly by creating another file. Let us name it SmsMessageUtil.kt
, duh.
Once the file is ready copy the code below. The code is an object which is equivalent of Java‘s singleton instance
.
object SmsMessageUtil {
const val TAG = "SmsMessageUtil"
const val KEY_PDUS = "pdus"
const val KEY_FORMAT = "format"
fun getSmsMessage(bytes: ByteArray?, format: String?): SmsMessage? {
if (bytes == null) return null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && format == null) return null
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
SmsMessage.createFromPdu(bytes, format)
} else {
SmsMessage.createFromPdu(bytes)
}
}
/**
* Convert and return the single message in the PDU(s).
*
* @return the convert message from the provided PDU(s)
*/
fun getSmsMessage(pdus: List<Any>?, format: String?): String {
val result = ArrayList<SmsMessage>()
pdus?.forEachIndexed { _, any ->
val sms = getSmsMessage(any.toByteArray(), format)
if (sms != null) {
result.add(sms)
}
}
return combineEachMessage(result)
}
/**
* Extract the message from [SmsMessage].
*
* @return the contents from the sender.
*/
private fun combineEachMessage(sms: List<SmsMessage>): String {
val final = StringBuilder()
sms.forEach {
final.append(it.messageBody)
}
return final.toString()
}
}
Code language: Kotlin (kotlin)
About the PDU in brief
You might have noticed something you might not have seen in the code above. Yes I am talking about the PDU. PDU is short for Protocol Data Unit.
It is nothing but the data with the protocols can be understood as a network packet. It contains all the information regarding the SMS message.
To learn more about PDU please refer to this article on Wikipedia.
The extension
Create a file named SmsExt.kt
( though you can name it anything you want ).
The code below just converts the instance of Any
to ByteArray
if it cannot be converted null
is returned instead.
fun Any.toByteArray(): ByteArray? {
return this as? ByteArray
}
Code language: Kotlin (kotlin)
Do note the file only contains the method above. No class or object, this is just an extension to existing Any
class.
Extensions are really very cool once you understand what they are. You can read more about extensions by clicking here.
TECHENUM
Registering SMS Broadcast Receiver in Android Manifest
We have successfully completed everything required. But if you run this code it will not work, why?
It is because we have to register the class in our AndroidManifest.xml
Let us see how we can do that as follows
<receiver
android:name=".receivers.IncomingSmsReceiver"
android:enabled="true">
<intent-filter android:priority="9999999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Code language: HTML, XML (xml)
Make sure to replace the android:name=".receivers.IncomingSmsReceiver"
with the package name your file is residing in. Because it might be different for you.
That is pretty much it. You do not need to do anything else. The broadcast receiver will contain the SMS contents, do whatever you like with it.
Also please do comment if I have missed out anything.
Happy CODING!
* The featured image is taken from codeEXA. No copyright infringement intended, image will be removed upon request of the Author.
Also Read: ZOOM SDK Android: Learn How to Create an Online Meeting
TECHENUM
Like!! Really appreciate you sharing this blog post.Really thank you! Keep writing.