4
votes

I have a task to periodically read the phone sensors (e.g. WiFi, accelerometer) in the backend.

My current solution is to use an AlarmManager.

Specifically, we have:

In the "main" program (an activity), we use PendingIntent.getService:

public class Main extends Activity {
...
Intent intent = new Intent(this, AutoLogging.class);
mAlarmSender = PendingIntent.getService(this, 0, intent, 0);
am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC, 0, 5*1000, mAlarmSender);
}

In the "AutoLogging" program (a service), we respond to the alarm periodically:

public class AutoLogging extends Service {
...
@Override
public void onCreate() {
   Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
}

@Override
public void onDestroy() {
   super.onDestroy();
   Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onUnbind(Intent intent) {
   Toast.makeText(this, "onUnbind", Toast.LENGTH_SHORT).show()
   return super.onUnbind(intent);
}

@Override
public void onStart(Intent intent, int startId) {
   super.onStart(intent, startId);
   Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show();
   // Read sensor data here
}

@Override
   public IBinder onBind(Intent intent) {
   Toast.makeText(this, "onBind", Toast.LENGTH_SHORT).show();
   return null;
}
}

My problem is:

When I use this alarm service, only OnCreate and OnStart are called at each alarm.

My questions are:

(1) Do we need to call OnDestroy (or onBind, onUnbind)?

(2) Is this a correct way to use AlarmManager (compared with "broadcase receiver")?

Thanks! Vincent

3

3 Answers

0
votes

AlarmManager just uses the pending intent and performs the intent action, i.e starting service in your case.On alarm expiry service is created using onCreate( if it is not already running ) and then started by calling onStart. After you finish reading the sensor data, you can stop the service using stopSelf() which will ultimately call onDestroy().You shouldn't call onDestroy(),onBind() or onUnBind() explicitly in the service.

If you use broadcast receiver with alarm manager you have to start this service in onReceive of receiver.Using Service seems appropriate to me in this case.

0
votes

If you want to schedule a job in android periodically instead of using an alarm manager you can use GCM network manager with the periodic task. This internally uses an alarm manager or job scheduler depending on the Android version. It is also easier to use with a more flexible option. This article is great - https://www.bignerdranch.com/blog/optimize-battery-life-with-androids-gcm-network-manager/

0
votes

Chiming in years late for anyone that stumbles upon this.

In terms of which method gets called when for services see this post here:

Android onCreate or onStartCommand for starting service

You'd want to trigger in the onStartCommand.