简体   繁体   中英

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 (eg 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");
}
}

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 (ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM