I am trying to learn about service and BroadCastReceiver. Code below is a service which runs all the time in the background. The problem is I don't know how it would affect the battery consumption.
My goal is to detect the screen on and off, so I need a running service in the background when the app is close or open...
Is it going to drain a lot of battery? Can you please explain it?
Thank you
public class MyService extends Service{
private static final String TAG = "MyService";
private BroadcastReceiver mScreenOnOffReceiver;
private BroadcastReceiver OnOffBroadcastReceiver;
private NotificationManager mNotificationManager;
private Notification barNotif;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// here to show that your service is running foreground
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent bIntent = new Intent(this, WidgetBroadCastReceiver.class);
PendingIntent pbIntent = PendingIntent.getActivity(this, 0 , bIntent, Intent.FLAG_ACTIVITY_CLEAR_TOP);
NotificationCompat.Builder bBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("STICKY")
.setContentText("Sub Title")
.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pbIntent);
barNotif = bBuilder.build();
this.startForeground(1, barNotif);
// here the body of your service where you can arrange your reminders and send alerts
Thread mThread = new Thread() {
@Override
public void run() {
// Register the ScreenOnOffReceiver.java
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mScreenOnOffReceiver = new ScreenOnOffReceiver();
registerReceiver(mScreenOnOffReceiver, filter);
// initialize and register mScreenOnOffReceiver (no need the BroadcastReceiver class)
OnOffBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.e("", "SERVICE Screen is: " + "turned OFF.....");
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.e("", "SERVICE Screen is: " + "turned ON......");
}
}
};
registerReceiver(OnOffBroadcastReceiver, new IntentFilter(filter));
}
};
mThread.start();
return START_STICKY;
}
@Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this, "My Service has Started", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
Toast.makeText(this, "MyService Stopped", Toast.LENGTH_SHORT).show();
unregisterReceiver(mScreenOnOffReceiver);
unregisterReceiver(OnOffBroadcastReceiver);
stopForeground(true);
}
}
In your code example, the service didn't do some operations (intensive computing, network request etc.) that consume battery. So personally I think it is not very obviously that your service will consume a lot of battery. But the service is kept after it's started, which means your app will take more memory footprint. In some way, I think large memory app will take more system's battery, the system need to do more extra work to keep the overall performance in a good state, these extra work need CPU, IO and memory's computing and read/write cycle that consume the battery.
Your didn't start a new thread in your service, which means all the work of your service will run on main thread. In this way, it will cause ANR
with high possibility if you do long time operation which blocks UI. In your example, you just start notification and register broadcast receiver, your app run smoothly and didn't complain ANR
because these two operation finish very soon. But you should be aware that.
Personally it's might be better if you put your BroadcastReceiver
to AndroidManifest.xml
, it's not very usual like the way you did.