60

I have been trying to get this program to work but so far having no luck. I cannot find where I am doing wrong. I'm not sure if there's something wrong with the code, or debugging.

I'm trying to be notified if a new SMS arrives.

Here is my program:

package Technicaljar.SMSBroadcastReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

public class SMSBroadcastReceiver extends BroadcastReceiver {

        private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
        private static final String TAG = "SMSBroadcastReceiver";

        @Override
        public void onReceive(Context context, Intent intent) {
             Log.i(TAG, "Intent recieved: " + intent.getAction());

                if (intent.getAction() == SMS_RECEIVED) {
                    Bundle bundle = intent.getExtras();
                    if (bundle != null) {
                        Object[] pdus = (Object[])bundle.get("pdus");
                        final SmsMessage[] messages = new SmsMessage[pdus.length];
                        for (int i = 0; i < pdus.length; i++) {
                            messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                        }
                        if (messages.length > -1) {
                            Log.i(TAG, "Message recieved: " + messages[0].getMessageBody());
                        }
                    }
                }
           }
    }

And the manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="Technicaljar.SMSBroadcastReceiver"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true" >
        <receiver android:name=".SMSBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>

    </application>
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest> 

I am sending SMS through Telnet, and I cannot see any Intent received messages in the logcat. Here is my logcat from the time of installation.

D/AndroidRuntime(  478): 
D/AndroidRuntime(  478): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
D/AndroidRuntime(  478): CheckJNI is ON
D/AndroidRuntime(  478): --- registering native functions ---
D/AndroidRuntime(  478): Shutting down VM
D/dalvikvm(  478): Debugger has detached; object registry had 1 entries
I/AndroidRuntime(  478): NOTE: attach of thread 'Binder Thread #3' failed
D/Mms:app (  220): getSmsNewMessageNotificationInfo: count=14, first addr=12345, thread_id=4
D/dalvikvm(  151): GC_EXPLICIT freed 391 objects / 22552 bytes in 65ms
D/dalvikvm(  220): GC_EXPLICIT freed 926 objects / 44840 bytes in 73ms

So the SMS seems to be received by the emulator, but looks like the no intents are firing. What am I doing wrong here? After installing, do I have to somehow 'start' this receiver? Because when I install, I get

 [2010-11-07 21:24:41 - SMSBroadcastReceiver] No Launcher activity found!
[2010-11-07 21:24:41 - SMSBroadcastReceiver] The launch will only sync the application package on the device!

So I'm wondering if something's wrong here.

Community
  • 1
  • 1
madu
  • 5,232
  • 14
  • 56
  • 96

9 Answers9

78

android.provider.Telephony.SMS_RECEIVED has a capital T, and yours in the manifest does not.

Please bear in mind that this Intent action is not documented.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    Thank you very much CommonsWare. That was the problem. It works fine now. Thank you. Also, can I ask why this Intent is not documented? – madu Nov 07 '10 at 14:35
  • I didn't know it is not documented. I see lots of people using this intent I never thought it is not documented. Thank you for the info. – madu Nov 07 '10 at 15:39
  • Is there a documented way to be notified if a short message arrives? – Janusz Dec 28 '10 at 10:08
  • 5
    @Janusz: No, unfortunately. The fact that 99% of the code necessary to process incoming SMSes exists in the SDK, and this constant does not, would suggest that this constant is unlikely to change. However, I do not recall any official statements to that effect, and they certainly have not put it in the SDK despite ample opportunity to do so. Developers of SMS clients simply need to be aware of the issue and watch new Android releases like a hawk. – CommonsWare Dec 28 '10 at 10:22
  • This intent may not be well documented but it is referenced in the public API documentation [here](http://developer.android.com/reference/android/telephony/SmsMessage.html) and as such is 'fair game' for any Android dev to use. – Phil Haigh Mar 27 '12 at 22:55
  • @Phil: You are welcome to your opinion. Google may not share it. Some of these things they open up (e.g., `CalendarContract`). Some of these things they close down (e.g., Gmail content provider). – CommonsWare Mar 27 '12 at 22:58
  • @CommonsWare I'm not disputing the fact that Google might choose to close down an API that is currently public. I'm just trying to draw a distinction between using a hidden API (such as the WiFi hotspot functionality) that is not included in the Android JavaDoc (and cannot be invoked except via reflection), and the public API for working with incoming SMS messages which is documented, and public. – Phil Haigh Mar 27 '12 at 23:12
  • @CommonsWare Thank you so much sir :) it's been four days and my broadcast receiver was not being invoked. the problem was smaller "t". the problem seems common one – Zeeshan May 07 '13 at 20:06
  • 1
    @CommonsWare Spotting that 'T' was the Hawk Eye job! Kudos! – Aman Alam May 23 '13 at 11:12
  • 3
    It's now documented in api 19 here https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_RECEIVED_ACTION – Muhammad Babar Sep 25 '14 at 06:46
  • @CommonsWare BroadcastReceiver is calling 2 times for one message received. – hasnain_ahmad Jun 12 '17 at 09:30
18

I tried your code and found it wasn't working.

I had to change

if (intent.getAction() == SMS_RECEIVED) {

to

if (intent.getAction().equals(SMS_RECEIVED)) {

Now it's working. It's just an issue with java checking equality.

Matt Ellen
  • 11,268
  • 4
  • 68
  • 90
anshul
  • 209
  • 3
  • 4
  • 8
    FYI: its always better to call .equals(..) from a non-null string. e.g - if (SMS_RECEIVED.equals(intent.getAction())) { – Yaadm Dec 24 '13 at 06:39
5

Also note that the Hangouts application will currently block my BroadcastReceiver from receiving SMS messages. I had to disable SMS functionality in the Hangouts application (Settings->SMS->Turn on SMS), before my SMS BroadcastReceived started getting fired.

Edit: It appears as though some applications will abortBroadcast() on the intent which will prevent other applications from receiving the intent. The solution is to increase the android:priority attribute in the intent-filter tag:

<receiver android:name="com.company.application.SMSBroadcastReceiver" >
  <intent-filter android:priority="500">
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
  </intent-filter>
</receiver>

See more details here: Enabling SMS support in Hangouts 2.0 breaks the BroadcastReceiver of SMS_RECEIVED in my app

Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
TheIT
  • 11,919
  • 4
  • 64
  • 56
  • 1
    http://android-developers.blogspot.no/2011/01/processing-ordered-broadcasts.html <-- Read the part about looking for changes made by other apps and also about the significance of priority "0" – Mr. Developerdude Nov 05 '14 at 00:11
3

Stumbled across this today. For anyone coding an SMS receiver nowadays, use this code instead of the deprecated in OP:

SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
SmsMessage smsMessage = msgs[0];
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
kjdion84
  • 9,552
  • 8
  • 60
  • 87
3

intent.getAction().equals(SMS_RECEIVED)

I have tried it out successfully.

RAM
  • 2,413
  • 1
  • 21
  • 33
Cathy
  • 31
  • 1
2

Your broadcast receiver must specify android:exported="true" to receive broadcasts created outside your own application. My broadcast receiver is defined in the manifest as follows:

<receiver
    android:name=".IncomingSmsBroadcastReceiver"
    android:enabled="true"
    android:exported="true" >
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

As noted below, exported="true" is the default, so you can omit this line. I've left it in so that the discussion comments make sense.

Phil Haigh
  • 4,522
  • 1
  • 25
  • 29
  • 4
    Nope. When a receiver has an intent filter it becomes exported automatically. See http://developer.android.com/guide/topics/manifest/receiver-element.html#exported – Adam Nybäck May 02 '13 at 18:49
  • Fair comment. I suspect this may have changed in a recent version of Android, my code was originally developed against Android 4.0. I'll update the answer. – Phil Haigh May 07 '13 at 10:43
1

For android 19+ you can get it in Telephony.Sms.Intents.SMS_RECEIVED_ACTION). There are more in the Intents class that 're worth looking at

Peter Chaula
  • 3,456
  • 2
  • 28
  • 32
1

I've encountered such issue recently. Though code was correct, I didn't turn on permissions in app settings. So, all permissions hasn't been set by default on emulators, so you should do it yourself.

Dracontis
  • 4,184
  • 8
  • 35
  • 50
0

android.provider.telephony.SMS_RECEIVED is not correct because Telephony is a class and it should be capital as in android.provider.Telephony.SMS_RECEIVED

RAM
  • 2,413
  • 1
  • 21
  • 33
Cool Java guy מוחמד
  • 1,687
  • 4
  • 24
  • 40