2

I am new to android development, I want my device to get GPS location every 40 seconds in background mode, even after the app got killed. For that, In MyAlarm.class, I have setRepeating the Alarm every 40 seconds to call a "RepeatingAlarm.class(which extends BroadcastReceiver)" using the pending intent. In the onReceive method of the "RepeatingAlarm.class" called every 40 seconds, I have created another pending intent to call MyReceiver.class(which extends BroadcastReceiver). I have passed this pending intent created in the "RepeatingAlarm.class" to a requestLocationUpdate function, to get the GPS location.

My problem is that, sometimes I will get the same lat and long values repeatedly every 40 seconds continuing about atleast 3 minutes.

Then, the onReceive method of my MyReceiver.class is calling every second, instead of calling once the GPS location got received. I have pasted my code below, Please help me with a solution.

MyAlarm.class

public void StartAlarm(Context context)
{
 AlarmManager alm=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
 Intent intent = new Intent(context, RepeatingAlarm.class);
 PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
 alm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 40000, pi);
}

RepeatingAlarm.class

public class RepeatingAlarm extends BroadcastReceiver
{
 public static LocationManager locationManager = null;
 public static PendingIntent pendingIntent = null;
 @Override
 public void onReceive(Context context, Intent intent) 
 {
   locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
   Intent intentp = new Intent(context, MyReceiver.class);
   pendingIntent = PendingIntent.getBroadcast(context, 0, intentp, PendingIntent.FLAG_UPDATE_CURRENT); 
   Criteria criteria = new Criteria(); 
   criteria.setAccuracy(Criteria.ACCURACY_FINE);
   provider = locationManager.getBestProvider(criteria, true);
   if(provider != null)
   {            
    locationManager.requestSingleUpdate(locationManager.GPS_PROVIDER, pendingIntent);
   }
 }
}

MyReceiver.class

public class MyReceiver extends BroadcastReceiver
{
 @Override
 public void onReceive(Context context, Intent intent) 
 {
  String locationKey = LocationManager.KEY_LOCATION_CHANGED;
  if (intent.hasExtra(locationKey)) 
  {

   Location location = (Location)intent.getExtras().get(locationKey);
   double mlatitude = location.getLatitude();
   double mlongitude = location.getLongitude();
   if(RepeatingAlarm.locationManager != null  && RepeatingAlarm.pendingIntent)
   {
     RepeatingAlarm.locationManager.removeUpdates(RepeatingAlarm.pendingIntent);
   }

  }
 }
}

In the above code, the GPS location is receiving good once in every 40 seconds. But, sometimes, if once GPS takes long time to get the location say 15 minutes, after that every 40 seconds the same previous location is repeating till about 4 minutes. This is my major problem.

Then, the MyReceiver.class is calling frequently every seconds. Please help me with some example lines of code to solve this issue. Thank You all.

Raj
  • 21
  • 3
  • If you want to know when the GPS gets a first-fix you can use the code from my answer to this question: http://stackoverflow.com/questions/19365035/location-servise-gps-force-closed/19366773#19366773 – cYrixmorten Apr 10 '14 at 12:06
  • @cYrixmorten: Can you please tell me why the location is duplicating(i.e., giving the same location) from the point after GPS takes long time to listen(in the bus or in the train or in the more congested public place). I think the mistake in my code, but i was unable to predict it. Thanks. – Raj Apr 10 '14 at 12:20
  • To be perfectly honest, I cannot tell the reason at the moment. Been a while since I dived into that stuff but I suspect that (despite the Criteria.ACCURACY_FINE criteria), it will return lastKnownLocation as long as the GPS has not found a first fix. These kinds of unreliable results in positions was the reason for me to go through the trouble of making some code that would tell me exactly when the device is able to provide accurate positions. – cYrixmorten Apr 10 '14 at 12:29
  • Sorry did not read the question properly, regarding duplicates it sounds pretty likely what ChuongPham writes in the comment of Kedarnath's answer – cYrixmorten Apr 10 '14 at 12:31
  • By the way. If your device generally is slow in finding GPS and it is running CyangenMod or otherwise rooted, then it might be using the wrong region server for AGPS. To fix this you can download FasterFix from Google Play. I am running CyanogenMod, live in Europe and it was using the server in North America which made it painfully slow at finding GPS signal. – cYrixmorten Apr 10 '14 at 12:44
  • There are so many apps which are using GPS to get the location perfectly. I want to resolve the mistake in my code in getting the GPS. Thanks. – Raj Apr 10 '14 at 12:51
  • Then I suggest trying out the code from my first comment and only use the returned locations once the first-fix has been made. – cYrixmorten Apr 10 '14 at 12:56

1 Answers1

0

As per the developer documents requestSingleUpdate() method "Register for a single location update using a named provider and pending intent."

You need to use requestLocationUpdates() method instead.

The second parameter of this method minimum time interval between location updates, in milliseconds will allow you to fetch location again & again.

Lucifer
  • 29,392
  • 25
  • 90
  • 143
  • I have Already tried the requestLocationUpdates() function also. Still, the duplicate location exists. Can you please tell me that, the way of broadcasting the pendingIntent is right in my code? both in StartAlarm.class and in RepeatingAlarm.class. Thanks. – Raj Apr 10 '14 at 11:55
  • @Raj: If you are going to use `requestLocationUpdates()`, then you don't need the AlarmManager method. It's one or the other, not both. That's why you're getting duplicate locations. – ChuongPham Apr 10 '14 at 11:58
  • I want to use requestSingleUpdates() function, with AlarmManager calling at an interval of every 40 seconds. And then, the onRecieve method in the MyReceiver.class is calling each and every seconds, from the moment of requestingSingleUpdates() gets called to the moment of getting gps. – Raj Apr 10 '14 at 12:04
  • @ChuongPham: Can you please tell me why the location is duplicating(i.e., giving the same location) from the point after GPS takes long time to listen(in the bus or in the train or in the more congested public place). I think the mistake in my code, but i was unable to predict it. Thanks. – Raj Apr 10 '14 at 12:21
  • Perhaps this [link](http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28long,%20float,%20android.location.Criteria,%20android.app.PendingIntent%29) explains how the `requestLocationUpdates()` method works - in particular, pay close attention to the first parameter `minTime`. In short, the `minTime` parameter already acts as a "timer", and because you also use the AlarmManager to schedule location updates, so hence, you're getting two location updates at the same time. – ChuongPham Apr 10 '14 at 12:28
  • @ChuongPham: I'm using only requestSingleUpdate(provider, pendingIntent) function in my code. There is no minTime parameter in the above function. – Raj Apr 10 '14 at 12:42
  • And no risk of StartAlarm getting called twice? I would also suggest trying PendingIntent.FLAG_CANCEL_CURRENT instead of PendingIntent.FLAG_UPDATE_CURRENT, cannot remember the details but seem to remember that to be a good idea when wanting to attach new information for each broadcast. – cYrixmorten Apr 10 '14 at 12:48
  • @Raj: All my comments above are referring to your first post _"I have Already tried the requestLocationUpdates() function also. Still, the duplicate location exists."_. Now, with regard to `requestSingleUpdate`, did you read the link I posted above? Because according to the docs, `requestSingleUpdate` will _"Register for a single location update using the named provider and a callback."_, which means you'll only get ONE location update, hence the location name never changes. – ChuongPham Apr 10 '14 at 12:49