Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper usuage of Background Service / Broadcast Receiver

I built an application for Android to auto-login to a specific Guest wireless network. I wanted this application to work and run even when the UI/Activity is not shown/running.

Currently it seems to work well, however I'm questioning the logistics of the design. My questions are:

  • Do I even need a service?
  • Is my design backwards? Should the Broadcast Receiver call the service to do the work?
  • Can you register the broadcast receiver in the manifest and not have to call it at all in code?
  • Are multiple calls to startService() bad? I know only 1 service runs, but how do I check if the service is already running before creating it?

The application has 3 components:

  1. Activity - which has a GUI for displaying current network information and Close / "Stop Service" buttons
  2. Service - all this service does is register a broadcast receiver
  3. Broadcast Receiver - this is what does most of the work. 3.

    • The Activity's onCreate() calls the Context.startService()
    • The Service onCreate() creates a notification icon and registers the broadcast receiver
    • The Broadcast Receiver onReceive() checks if the network state has changed intent, then checks if currently connected to a specific SSID, then calls a special class I made to register / check if authenticated.
like image 812
The Unique Paul Smith Avatar asked Jul 16 '12 16:07

The Unique Paul Smith


People also ask

Can broadcast receiver run in background?

The alternative is to register the receiver in the AndroidManifest. This ensures that the BroadcastReceiver runs all the time, even when the app is backgrounded. I chose this option because I want my application to receive Bluetooth events even when the app isn't in use (i.e. backgrounded). In my AndroidManifest.

What is the current recommended way to handle long running background tasks?

Recommended solutionScheduling deferred work through WorkManager is the best way to handle tasks that don't need to run immediately but which ought to remain scheduled when the app closes or the device restarts.


1 Answers

Do I even need a service?

It depends. If the work you are doing within the BraodcastReceiver doesn't take much time then you can do it there. However, if your onReceive() runs too long then Android will kill it. In general you shouldn't do network I/O within the BroadcastReceiver. So you can use the BroadcastReceiver to just kick off your service and it can do the real work.

Is my design backwards? Should the Broadcast Receiver call the service to do the work?

See my answer to the first question (above)

Can you register the broadcast receiver in the manifest and not have to call it at all in code?

Yes, you can add an <intent-filter> tag to the <receiver> tag in the manifest. This will start your BroadcastReceiver automatically whenever the appropriate Intents are broadcast. Your application does not need to be running to have this happen. Something like this:

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

Are multiple calls to startService() bad? I know only 1 service runs, but how do I check if the service is already running before creating it?

Multiple calls to startService() are fine. If it is already started, it won't start another one. Each call to startService() generates a call to onStartCommand() in your service. If you want to see if it is already running, you can use peekService() from your BroadcastReceiver. This will return an IBinder if it is running, but won't start it if it isn't already running.

Also see android.net.wifi.STATE_CHANGE: not triggered on Wifi disconnect

like image 63
David Wasser Avatar answered Oct 12 '22 05:10

David Wasser