What I'm attempting to do is when receiving a c2dm message, start a service that asks for location for 'x' amount of time and then hands that location off to our server. The c2dm message starts the service correctly, and the GPS location turns on, but it never updates. It just sits there for the length of time I specify (currently 12 seconds) in the thread and does nothing. I'm using the exact same code somewhere else in my app (not as a service) and it works perfectly. What am I doing wrong?
This starts the service when receiving a c2dm message.
context.startService(new Intent(context, ServicePingLocation.class));
This is the code for the service itself. All that ever gets called, is "onCreate" and "onStart".
public class ServicePingLocation extends Service implements LocationListener {
private final String DEBUG_TAG = "[GPS Ping]";
private boolean xmlSuccessful = false;
private boolean locationTimeExpired = false;
private LocationManager lm;
private double latitude;
private double longitude;
private double accuracy;
@Override
public void onLocationChanged(Location location) {
Log.d(DEBUG_TAG, "onLocationChanged");
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
}
@Override
public void onProviderDisabled(String provider) {
Log.d(DEBUG_TAG, "onProviderDisabled");
Toast.makeText(
getApplicationContext(),
"Attempted to ping your location, and GPS was disabled.",
Toast.LENGTH_LONG).show();
}
@Override
public void onProviderEnabled(String provider) {
Log.d(DEBUG_TAG, "onProviderEnabled");
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(DEBUG_TAG, "onStatusChanged");
}
@Override
public void onCreate() {
Log.d(DEBUG_TAG, "onCreate");
}
@Override
public void onDestroy() {
Log.d(DEBUG_TAG, "onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(DEBUG_TAG, "onBind");
return null;
}
@Override
public void onStart(Intent intent, int startid) {
Log.d(DEBUG_TAG, "onStart");
lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,
300f, this);
Log.d(DEBUG_TAG, lm.toString());
new SubmitLocationTask(ServicePingLocation.this).execute();
}
private void locationTimer() {
new Handler().postDelayed(new Runnable() {
// @Override
@Override
public void run() {
locationTimeExpired = true;
}
}, 12000);
}
private class SubmitLocationTask extends AsyncTask<String, Void, Boolean> {
/** application context. */
private Context context;
private Service service;
public SubmitLocationTask(Service service) {
this.service = service;
context = service;
}
@Override
protected void onPreExecute() {
locationTimer(); // Start 12 second timer
}
@Override
protected void onPostExecute(final Boolean success) {
if (success && xmlSuccessful) {
lm.removeUpdates(ServicePingLocation.this);
onDestroy();
} else {
if (!GlobalsUtil.DEBUG_ERROR_MSG.equals(""))
Toast.makeText(getBaseContext(),
GlobalsUtil.DEBUG_ERROR_MSG, Toast.LENGTH_SHORT)
.show();
GlobalsUtil.DEBUG_ERROR_MSG = "";
}
}
@Override
protected Boolean doInBackground(final String... args) {
try {
DateFormat df = null;
df = new SimpleDateFormat("M/d/yy h:mm a");
Date todaysDate = new Date();// get current date time with
// Date()
String currentDateTime = df.format(todaysDate);
while ((accuracy > 100f || accuracy == 0.0)
&& !locationTimeExpired) {
// We just want it to sit here and wait.
}
return xmlSuccessful = SendToServerUtil.submitGPSPing(
0, longitude,
latitude, accuracy, currentDateTime);
} catch (Exception e) {
return false;
}
}
}
}
[Edit] Fixed the issue I was having. Code was actually working. I added the network provider, adjusted the onDestroy() method to stop the service, and tweaked the time used to grab GPS signal.
Thank you for the advice, CommonsWare
LocationPoller
, which is designed for scenarios like this. – Settlement