2

I have an activity where I can tap a button to start a BroadcastReceiver, which listens for changes of the wifi connection. Now when the activity is showing or I leave the app (press the home button) while the activity is showing the receiver works fine. If I however end the activity or kill the app as a whole (that is swipe it away in the recent tasks list) the receiver does not work anymore. The structure of my activity which includes the receiver looks like this:

MainActivity.java

...

public class MainActivity extends AppCompatActivity {
...
    public BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
        ...
        }
    }
}

I have read about Services and JobSchedulers and figured that I will probably have to use one of these to get my receiver running at anytime. I just don't really know how to implement these. Can anyone explain to me how to do that? Also, is it a good idea to include the BroadcastReceiver in the MainActivity class or should I rather define it in a separate class?

Thanks a lot!

Philipp
  • 404
  • 1
  • 5
  • 17

1 Answers1

2

You're creating a Context-registered receivers, as per the docs:

Context-registered receivers receive broadcasts as long as their registering context is valid. For an example, if you register within an Activity context, you receive broadcasts as long as the activity is not destroyed. If you register with the Application context, you receive broadcasts as long as the app is running.

You can create your BR in a separate file and register it in your manifest file so it will be called when your intent filter is matched:

<receiver android:name=".wifiStateReceiver"  android:exported="true">
    <intent-filter>
       <action android:name="android.net.wifi.STATE_CHANGE" />
    </intent-filter>
</receiver>

When the intent filter is matched your onReceive method inside your BR will be called.

public class wifiStateReceiver extends BroadcastReceiver {

   @Override
   public void onReceive(Context context, Intent intent) {
      //do some quick processing and call an activity
   }
}
Levi Moreira
  • 11,917
  • 4
  • 32
  • 46
  • Thanks a lot for the quick reply, that sounds good. However, I really only need my BR to be running after tapping the button. Is there a way I con do this with your method? And am I completely wrong with the idea about services and job schedulers or are they actually an alternative? – Philipp May 22 '18 at 19:00
  • With BRs you only have either the context-registered ones or the manifest ones. If you need it working only when you tap, then you bound to use the context-registered ones that will stop working when the context is destroyed. – Levi Moreira May 22 '18 at 19:05
  • The problem with services is the same with the activity, your BR will be context registered and it will be stopped when the context (this time the Service) is destroyed. Moreover, it's not a good pattern to have a running service to keep a broadcast receiver active – Levi Moreira May 22 '18 at 19:06
  • JobSchedulers are meant for deffered work, which I think is not exactly what you're looking for – Levi Moreira May 22 '18 at 19:08
  • I see. But then how do apps like the stock android alarm clock work? I saw that this particular one uses also BR's and I do get the alarm even after killing the app entirely. – Philipp May 22 '18 at 19:25
  • Maybe you're after the AlarmManager api https://developer.android.com/reference/android/app/AlarmManager – Levi Moreira May 22 '18 at 19:30
  • I have read a little about AlarmManager and I am not quite sure whether this is what I need. I think I am going to try enable/disable the receiver in the manifest programatically from the MainActivity class. Dou you think this might work? – Philipp May 22 '18 at 20:28
  • Will it work with an API lever after 26? because Android docs says no – Mohsen Emami Jul 07 '23 at 07:24