stud91
stud91

Reputation: 1854

Periodic location updates in a Service (Android)

I am trying to implement a service that once started continues forever (unit OS forcibly closes it due to lack of resources). This services obtains user's location say every five minutes. In my implementation the service works if the application is sent to background but stops when the application is terminated.

Can you also suggest how to get periodic updates (e.g. get location after 5 mins)

GeoFenceService.java

public class GeoFenceService extends Service {

private Context mContext;

private List<TestMalls> mTestMalls ;
private MyLocationManager mLocationManager;
private HashMap<Integer, Double> mallDistances;

private ServiceHandler mServiceHandler;
private Looper mServiceLooper;

@Override
public void onCreate(){
    super.onCreate();
    mContext = getBaseContext();

    this.mLocationManager = MyLocationManager.getInstance();
    HandlerThread thread = new HandlerThread("ServiceStartArguments", android.os.Process.THREAD_PRIORITY_BACKGROUND);
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startid){

    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startid;
    mServiceHandler.sendMessage(msg);

    return START_STICKY;
}

private final class ServiceHandler extends Handler {

    public ServiceHandler(Looper looper){
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {

        Toast.makeText(mContext, "Service running ... ", Toast.LENGTH_SHORT).show();

        mLocationManager.startListenLocation(mContext);

        while (mLocationManager.hasLocation()) {

            for (TestMalls t : mTestMalls) {
                mallDistances.put(t.mallId, (double) mLocationManager.distanceInMetersFromLocation(t.latitude, t.longitude));
            }

            Iterator bt = mallDistances.entrySet().iterator();
            while (bt.hasNext()) {
                Map.Entry<Integer, Double> pair = (Map.Entry<Integer, Double>) bt.next();
                Log.v("Hash Map Distances", "Id: " + String.valueOf(pair.getKey()) + " Distance " + String.valueOf(pair.getValue()));
                bt.remove();
            }
        }
    }
}

@Override
public void onDestroy() {
    Log.v("Service", "done - finished");
}
}

Upvotes: 0

Views: 286

Answers (1)

Yash Sampat
Yash Sampat

Reputation: 30601

Create a PendingIntent with the getService() method and add it to the AlarmManager to repeat every 5 minutes. Ensure that the Service stops itself after completing its work (i.e. call stopSelf() at the end).

Intent i = new Intent(getApplicationContext(), LocationService.class);
PendingIntent pi = PendingIntent.getService(getApplicationContext(), requestCode, i, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, 0,
            5*60*1000, pi);

Assuming that your Service works properly, this will work.

Upvotes: 3

Related Questions