8

Can anybody tell me a way to create an in-application BroadcastReceiver? I have created BroadcastReceiver which Toasts a message. It works even when the application is in background state, I want it to work only when application is in foreground.

  public class MainActivity extends Activity {

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                this.registerReceiver(this.mConnReceiver, new IntentFilter(
                        ConnectivityManager.CONNECTIVITY_ACTION));
            }

            private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {

                public void onReceive(Context context, Intent intent) {
                    boolean noConnectivity = intent.getBooleanExtra(
                            ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                    String reason = intent
                            .getStringExtra(ConnectivityManager.EXTRA_REASON);
                    boolean isFailover = intent.getBooleanExtra(
                            ConnectivityManager.EXTRA_IS_FAILOVER, false);

                    NetworkInfo currentNetworkInfo = (NetworkInfo) intent
                            .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                    NetworkInfo otherNetworkInfo = (NetworkInfo) intent
                            .getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);

                    if (currentNetworkInfo.isConnected()) {
                        System.out.println("Connected");
                        Toast.makeText(getApplicationContext(), "Connected",
                                Toast.LENGTH_LONG).show();
                    } else {
                        System.out.println("Not Connected");
                        Toast.makeText(getApplicationContext(), "Not Connected",
                                Toast.LENGTH_LONG).show();
                    }
                }
            };

        }

So here is my code which is checking network state and generating a BroadcastReceiver. I haven't added anything in manifest.
Rishabh Srivastava
  • 3,683
  • 2
  • 30
  • 58

2 Answers2

2

There are a number of ways to do this. The first 2 I can think of are like this:

  1. If your <receiver> is declared in the manifest with an <intent-filter>, you can enable it and disable it from your application so that it is only enabled when the app is in the foreground. To do this, initially set the receiver disabled by adding android:enabled="false" to the manifest entry for <receiver>. Now, when your app is running, in onResume() you want to enable the receiver. Use PackageManager.setComponentEnabledSetting() to do this. When your activity goes to the background, in onPause() you can disable the receiver again.

  2. Dynamically register and unregister the receiver. For this you don't need to declare the receiver in the manifest. In your application, create an instance of your BroadcastReceiver and in onResume() call registerReceiver() with the appropriate intent filter. When the app goes to the background, in onPause() call unregisterReceiver() to remove it. The receiver will only receive calls to onReceive() while the app is in the foreground.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • yes, that's fine. Just move the `registerReceiver()` call from `onCreate()` to `onResume()` and add `unregisterReceiver()` call to `onPause()`. – David Wasser Sep 11 '13 at 10:19
  • but now as soon as I resume the activity it toasts "Connected" while my requirement is to detect the network change and then toast not when the activity is resumed. – Rishabh Srivastava Sep 11 '13 at 10:32
  • 1
    Yes, the problem here is that the broadcast intent you are listening for is a "sticky" intent. That means that the Android framework keeps around the most recent state and whenever a broadcast receiver is registered it immediately triggers with the most recent state. To get around this, in `onReceive()` you can call `isInitialStickyBroadcast()`. If this returns `true` then you can ignore the call to `onReceive()` because this is just informing you of the current state. – David Wasser Sep 11 '13 at 11:12
1

see Context.registerReceiver() and Context.unregisterReceiver()

pskink
  • 23,874
  • 6
  • 66
  • 77