Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Cell Broadcast message?

Tags:

android

I try to get text of Cell Broadcast message just like sms, but it does'not work:

public class SMSReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "";
    if (bundle != null) {
        // ---retrieve the SMS message received---
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            str =msgs[i].getOriginatingAddress();
            str += " :";
            str += msgs[i].getMessageBody().toString();

Do you know any way to get it?

like image 286
VVS Avatar asked Aug 19 '11 07:08

VVS


People also ask

What does it mean when my phone says cell broadcast?

Cell Broadcast is a technology that's part of GSM standard (Protocol for 2G cellular networks) and has been designed to deliver messages to multiple users in an area. The technology is also used to push location-based subscriber services or to communicate area code of Antenna cell using Channel 050.

What does broadcast message mean on Android?

With Google Assistant, you can broadcast voice messages to your Google Family Group. These family broadcasts play on speakers, Smart Displays, and Smart Clocks in your home, and are sent as notifications and audio files to family members' phones and tablets.


1 Answers

I also spent some time on investigation of this question. And it seems that there is no public API to do that. But I can share some results from my reverse engineering research...

My Samsung Galaxy S is able to receive CB messages, so I decompiled SMS app and looked into the code. It has the following BroadcastReceiver in its manifest file:

    <receiver android:name=".transaction.PrivilegedSmsReceiver">
        ...
        <intent-filter>
            <action android:name="android.provider.Telephony.CB_RECEIVED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.provider.Telephony.CB_SETTINGS_AVAILABLE" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.provider.Telephony.SET_CB_ERR_RECEIVED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.provider.Telephony.GET_CB_ERR_RECEIVED" />
        </intent-filter>
    </receiver>

Note the android.provider.Telephony.CB_RECEIVED intent-filter. I did not find any documentation about it, but from its name I assumed that it's the only broadcast that I need to catch for now.

Then I searched through the code of decompiled apk and found that it uses android.provider.Telephony.Sms.Intents->getCbMessagesFromIntent() interface to access retrieve CB messages, which returns CbMessage class instance. This interface is outdated even for simple SMS messages, so I assumed that CbMessage should work with pdus as SmsMessage does. Finally I found the source of SmsCbMessage class which is pretty similar to SmsMessage by API. It depends on 5-6 internal Android java files, so for simplicity I just grab them from the same site and included them into my project. The broadcastReceiver is the same as yours except the class SmsMessage is replaced by SmsCbMessage:

public class CbReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //---get the CB message passed in---
        Bundle bundle = intent.getExtras();        
        SmsCbMessage[] msgs = null;
        String str = "";            
        if (bundle != null)  {
            //---retrieve the SMS message received---
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsCbMessage[pdus.length];            
            for (int i=0; i<msgs.length; i++) {
                msgs[i] = SmsCbMessage.createFromPdu((byte[])pdus[i]);                
                str += "CB lang " + msgs[i].getLanguageCode();                     
                str += " :";
                str += msgs[i].getMessageBody().toString();
                str += "\n";        
            }
            //---display the new CB message---
            abortBroadcast();
            Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
        }                         
    }
}

After installing my application into my SGS phone with the receiver above, and enabling receiving CB messages in phone SMS application, my app was able to show CB messages in toast in parallel with receiving them by standard SMS application.

The issues are still needed to be resolved:

  • How to enable/disable/configure_channels of CB messages in my application? SMS app uses getCbSettings()/setCbSettings() functions, but I did not find them. So temporarily I used other app for that.
  • How to abort CB message broadcast, so other apps do not receive them? It seems abortBroadcast() does not work here, because the broadcast message is not ordered (isOrderedBroadcast() returns false).
like image 153
GrAnd Avatar answered Oct 07 '22 02:10

GrAnd