Search code examples
androidsmsbroadcastreceiverandroid-4.0-ice-cream-sandwichsmsmanager

Reading SMS not working


I have written below method to read the incoming sms text. This code is working perfectly in Android 4.04 when the default SMS client is the native SMS client, but when the SMS client is Hangout the method does not work.

The same method works in Android 5 with Hangout as the SMS client, the problem is only in Android 4.04 with Hangout as SMS client. Please let me know if I am missing anything.

static boolean readSMS(Intent intent, int code) {
    try {
        Bundle bundle = intent.getExtras();
        if (bundle != null) {
            Object[] pdusObj = (Object[]) bundle.get("pdus");
            for (int i = 0; i < pdusObj.length; i++) {
                SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                String message = currentMessage.getDisplayMessageBody();
                if (message.contains(String.valueOf(code)))
                    return true;
            }
        }
    } catch (Exception e) {
        return false;
    }
    return false;
}

The method is invoked from the java code within a BroadCastReceiver.

     receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Bundle bundle = intent.getExtras();
                    if (bundle != null) {
                     if (readSMS(intent, code)) {
                    ------------------
                    }
                }

The BroadCastReceiver is invoked as:

   context.registerReceiver(receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));

Manifest.xml

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

Solution

  • The incoming SMS is a Broadcast transmission which you can register a receiver to listen to it and respond according to your logic. You can register multiple receivers to the SMS broadcast, and they will all get the SMS, one by one, by a certain order.
    How can we know the order? Each receiver has a priority, and the OS dispatches the SMS from the higher priority receiver to the lower ones.
    Upto Android 4.4 (excluding), you could have use the abortBroadcast(); statement, which would terminate the dispatching. Lets say that we have two apps - A and B with SMS receivers. If A has higher priority than B and A uses the abort statement, then app B wil never get the SMS. From Android 4.4 and on, you can't abort SMS transmissions anymore.
    From your question it looks like that when you use Android 4.0.4 the Hangout client has a higher priority from your app, and it aborts the broadcast transmission, while the default client does not abort it (or has a lower priority). When you switch to Android 5, the Hangout cannot abort the SMS, so your app works as it should.
    As to the priorities - the documentation states that "The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.".
    You can add to your menifanifest the line

    <intent-filter android:priority="999">
    

    and hope that the Hangout's priority is lower.