Reputation: 334
I have a fairly straightforward piece of code, which is is a Service that runs periodically, records the current location (using network provider), sends it to the server, then goes back to sleep.
I am testing this on two different phones - an SGS2 with a regular monthly plan and a cheapo ZTE with a prepaid SIM card (has data, but minutes are 10c/min). I've found that when I take both phones and go for a drive, the SGS2 works perfectly fine, but ZTE seems to lose the ability to get a fix.
The ZTE wakes up, sets up the listener, gets a location fix, however the location points to my house (where it got the last wifi-based fix), not the true current location. The timestamp of the location is up to date, so when I receive a location update, I really can't tell whether the location is valid (as in the SGS2, or when the ZTE is at home) or bunk (such as when I'm driving with the ZTE).
Has anyone seem similar problems before? Does it have anything to do with the prepaid card, or the ZTE phone itself? Unfortunately, I can't swap the SIM cards (I would have to root/unlock the phones), so I can't test that out.
I've included the code below, but since it works fine on the SGS2, I don't think there's much of a problem.
public class LocationRecorder extends Service {
private volatile Location lastLocation;
private LocationManager locationManager;
private LocationListener locationListener;
private static volatile PowerManager.WakeLock wakeLock = null;
private static synchronized PowerManager.WakeLock getWakeLock(Context context) {
if (wakeLock == null) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationRecorder");
wakeLock.acquire();
}
return wakeLock;
}
public static void startLocationRecorder(Context context, Intent service) {
getWakeLock(context);
context.startService(service);
}
@Override
public void onCreate() {
Log.d("LocationRecorder", "Starting Location Service");
locationManager = ((LocationManager)getSystemService(LOCATION_SERVICE));
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.d("Location Changed", location.toString());
if (location.getExtras()!=null) {
String x = "";
for (String key : location.getExtras().keySet()) {
x+=key+":"+location.getExtras().get(key).toString()+", ";
}
Log.d("Location Changed Extras", x);
}
setLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Status Changed", provider+" "+status);
if (extras!=null) {
String x = "";
for (String key : extras.keySet()) {
x+=key+":"+extras.get(key).toString()+", ";
}
Log.d("Status Changed Extras", x);
}
}
public void onProviderEnabled(String provider) {
Log.d("Provider Enabled", provider);
}
public void onProviderDisabled(String provider) {
Log.d("Provider Disabled", provider);
}
};
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
waitForLocation();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
locationManager.removeUpdates(locationListener);
try {
wakeLock.release();
wakeLock = null;
}
catch (Exception e) {
wakeLock = null;
}
Log.d("LocationRecorder", "Destroying service");
super.onDestroy();
}
protected void waitForLocation() {
new Thread() {
@Override
public void run() {
setLocation(null);
for (int i=0; i<3;i++) {
Log.d("LocationRecorder", "Waiting for location");
try {Thread.sleep(10000);} catch(Exception e) {};
if (getLocation() != null) {
Log.d("LocationRecorder", "Sending new location!");
new Utilities(LocationRecorder.this).updateLocation(getLocation().getLatitude(),
getLocation().getLongitude(), getLocation().getAccuracy());
break;
}
}
stopSelf();
}
}.start();
}
public synchronized void setLocation(Location newLocation) {
lastLocation = newLocation;
}
public synchronized Location getLocation() {
return lastLocation;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
Upvotes: 2
Views: 3257
Reputation: 1881
This is expected behaviour. You may just need to wait longer before you destroy the location manager to get a more up to date location.
Here's a better description from Google Developer Docs.
Upvotes: 3