Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Periodic GPS location updates with AlarmManager inside a Service

I read a lot of questions on here but couldn't figure out what the problem is.

I'm writing a field service application for Android. In one of the Activities (MyActivity.java) I have two buttons: Start and Stop.

When the field worker presses start I need to get his current location with GPS and send it to server in timely intervals (say it be 5 minutes default, here I set it to 20 secs. for testing). The customer wants this to see how long the workers spend time in traffic, the traffic in my city (Istanbul) is a mess.

I have an AlarmManager in my activity, when the start button is pressed the alarm is set by AlarmManager.setRepeating() to start the service (ServiceClass.java).

Intent intent = new Intent (MyActivity.this, ServiceClass.class);
mPendingIntent = PendingIntent.getService(MyActivity.this, 0, intent,
                                              PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mAlarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 20*1000,
                                                                  mPendingIntent);

I cancel the Alarm with the Stop button.

It works perfectly till here, the Service starts. Its onCreate(), onStart() and onDestroy() methods are executed. But I can't get the location. I'm not working on a real device so I'm using DDMS to send locations. But the application skips that step and prints Longitude and Latitude of my location as Lon:0 Lat:0.

Here's the code inside the service:

public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    Log.d("Testing", "Service got started, calling location updates:");
    mLocationManager.requestSingleUpdate(mCriteria, mLocationListener,
                                                                getMainLooper());
    Log.i("TESTING LOCATION UPDATE: LOCATION:", "\nLat:"   + mLatitude +
                                                          "  Lon:" + mLongitude);
    stopSelf(startId);
    Log.d("Testing", "Service Stopped!");

And finally, here's my LocationListener:

 mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {

            if(location != null){
                mLatitude = location.getLatitude();
                mLongitude = location.getLongitude();
                Log.i("onLocationChanged(Location location)", "Lat:"+mLatitude + "
                                                            Lon:" + mLongitude);
}

Also something caught my eye, when I run the code:

mLocationProvider = mLocationManager.getBestProvider(mCriteria, true);
Log.i("BEST PROVIDER IS:", mLocationProvider);

It says BEST PROVIDER IS: gps. But this log inside onProviderEnabled() is never shown in logcat.

@Override
public void onProviderEnabled(String s) {
    Log.v("onProviderEnabled", "ENABLED");
}

Two things to add, if I use:

mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                                                              mLocationListener);

it doesn't work either.

This however works and I can get the LastKnownLocation:

Location lastKnown = mLocationManager.getLastKnownLocation(
                                                   LocationManager.GPS_PROVIDER);

First of all, is this a good approach for doing this? If it is please check to see what I am missing. If it is not, can you please tell me how can I implement this any better?

Thank you. :)

like image 884
Lev Avatar asked Jan 18 '23 02:01

Lev


2 Answers

First, you cannot register for location updates, then shut down the service. At best, you will leak threads. At worst, Android will terminate your process (thinking there is nothing running in it) and you will not get the update. Also, GPS takes a while to warm up, so you might not get a fix within 20 seconds, particularly in an urban setting. Also, you have to make sure the device stays awake while you are trying to collect a fix.

As a result, getting periodic location fixes in the background is a rather complicated problem.

I wrote a now-discontinued LocationPoller to try to address this, and another developer has forked and extended it. You could try the fork or simply use it as a source of ideas.

like image 73
CommonsWare Avatar answered Jan 20 '23 02:01

CommonsWare


try this:

AlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,,,);

I am doing for get one's current location with GPS, but my project works every 10 seconds. I have no idea now. And my code :

AlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),6000000,pi);
like image 27
user2210048 Avatar answered Jan 20 '23 02:01

user2210048