Question

I want to develop a single activity android text messaging application that receives messages from a particular phone number. All other messages are to be sent to the inbox. For this purpose, I registered a BroadcastReceiver in the AndroidManifest.xml which checks for the incoming message's phone number and then aborts the broadcast if the number matches. The message is then stored in a sqlite database which is used to display messages in a ListActivity.

However, the issue I am facing is the broadcast is not received consistently by my app, sometimes it receives the intended message and sometimes it does not(goes to inbox). The message is received in th app as long as the app is opened, and a bit after it is closed. It is simply not consistent. I gave my app a higher priority (999) in the manifest.

My Manifest is below: `

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<application
    android:icon="@drawable/app_icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:allowBackup="true">

    <activity
        android:launchMode="singleInstance"
        android:name="org.trial.hiv.HIVActivity"
        android:label="@string/title_activity_hiv"
        android:exported="true">
            <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.BOOT_COMPLETED" />
                 <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
    </activity>

    <receiver android:name="org.trial.hiv.SMSReceiver"
          android:exported="true">
        <intent-filter android:priority="999">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
         </intent-filter>
    </receiver>

    <service android:name="org.trial.hiv.SMSService" ></service>

    <receiver android:name="org.trial.hiv.BootReceiver"
          android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
         </intent-filter>
    </receiver>

    <service android:name="org.trial.hiv.BootUpService" ></service>

</application>

`

And my SMSReceiver.java, which starts a service to perform necessary housekeeping tasks on the message received...

public class SMSReceiver extends BroadcastReceiver
{
 public void onReceive(final Context context, Intent intent)
   {
    Intent smsServiceIntent = new Intent(context, SMSService.class);
    smsServiceIntent.setClass(context, SMSService.class);

    Bundle bundle = intent.getExtras();
    Object pdus[] = (Object[]) bundle.get("pdus");
    SmsMessage smsMessage[] = new SmsMessage[pdus.length];
    for (int n = 0; n<pdus.length; n++)`
    {
        smsMessage[n] = SmsMessage.createFromPdu((byte[]) pdus[n]);
    }
    String sender = smsMessage[0].getOriginatingAddress();
    String body = smsMessage[0].getMessageBody();

    if (sender.equalsIgnoreCase(activity.number))//incoming number is checked
            {
        this.abortBroadcast();
        smsServiceIntent.putExtra("sender", sender);
        smsServiceIntent.putExtra("body", body);
        context.startService(smsServiceIntent);
    }
    }   
}

I am using an smsService because I read that the BroadcastReceiver must not to any task for more than 10 seconds though I simply write the message to a SQLiteDatabase, I thought I still use a service.

Could someone point out where I am going wrong, or if I am missing out something critical. My requirement is to always receive all messages from a given number in my app, at any time.

Was it helpful?

Solution

After much debugging and understanding how BroadcastReceivers work in Android, I understand that the broadcast intent needs to be polled for, which I never did and hence the inconsistent behaviour... the following chage in code resolved my issue

do
{
bundle = intent.getExtras();
}
while (bundle == null);

in the onReceive() method of the BroadcastReceiver, and it resolved my issue. I could not find this documented anywhere, even in several SMS App tutorials.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top