Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Broadcast Receiver not being called

I am trying to build a simple app that will wait until a new SMS arrives, extract and process the data from it. The application should run in the background. The GUI has a single switch element to start/stop the broadcast receiver. Even if the app is destroyed and the screen is locked, the app should still be working unless the user manually turns it off. I searched every resource on stackoverflow, and most of them did it this way, yet, it still does not work for me, and I can't seem to know why. I know because Log.d(...) is not returning anything. Any help would be appreciated.

enter image description here

Broadcast SMS Receiver

public class SMSReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("RECEIVER", "ENTERED");

        if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
            Log.d("RECEIVER", "SMS RECEIVED");

            SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
            for(int i = 0; i < 4; i++){
                SmsMessage sms = messages[i];
                Log.d("Message " + i + 1 + " from: ", sms.getOriginatingAddress());
                Toast.makeText(context,"SMS from " + sms.getOriginatingAddress(), Toast.LENGTH_SHORT).show();
            }
        }

    }
}

Main Activity

public class MainActivity extends AppCompatActivity {
    IntentFilter filter;
    SMSReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        filter = new IntentFilter();
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        receiver = new SMSReceiver();

        Switch startSwitch = (Switch) findViewById(R.id.startSwitch);
        startSwitch.setChecked(false);

        startSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                if(isChecked){
                    getApplication().registerReceiver(new SMSReceiver(), filter);
                } else {
                    getApplication().unregisterReceiver(receiver);
                }
            }
        });

    }
}

Manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ahmad.smsforwarder">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

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

</manifest>
like image 252
Ahmad Tn Avatar asked Mar 04 '17 17:03

Ahmad Tn


People also ask

How do you trigger a broadcast receiver?

Creating a BroadcastReceiverThe onReceiver() method is first called on the registered Broadcast Receivers when any event occurs. The intent object is passed with all the additional data. A Context object is also available and is used to start an activity or service using context. startActivity(myIntent); or context.

What is broadcast receiver in an Android app?

Definition. A broadcast receiver (receiver) is an Android component which allows you to register for system or application events. All registered receivers for an event are notified by the Android runtime once this event happens.

In which thread does a broadcast receiver run?

When you Register for any Broadcast receiver by Default onReceive() method will be called on the Main Thread( UI Thread). But If we want to do any heavy operations or if your broadcast is calling multiple times, then so much load will be accumulated on Main Thread which is not recommended.


2 Answers

You have to register your receiver in AndroidManifest.xml with specific intent in intent filter.

    <receiver
        android:name=".SMSReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
like image 62
Sanyam Jain Avatar answered Sep 24 '22 21:09

Sanyam Jain


I suffered too long to find out that as of Android 6.0 (API 23), you will have to register permissions in the main activity java class as well. I fixed the problem by adding the following lines to the main activity's class onCreate() Method:

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS},1);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECEIVE_SMS},1);
like image 37
Ahmad Tn Avatar answered Sep 24 '22 21:09

Ahmad Tn