sms broadcast receiver in android

Implement SMS Broadcast Receiver in Android

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

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&lt;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&lt;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.

Also Read: How to learn programming and where to start ?

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

Related Posts

One thought on “Implement SMS Broadcast Receiver in Android

  1. Like!! Really appreciate you sharing this blog post.Really thank you! Keep writing.

Comments are closed.