I am working on a location aware application and I have come to a standstill. What I want to do is be able to ask the Android device for a single GPS location and return it.
So far this is what I have. A service that is supposed to update the location periodically:
import android.app.Service;
import android.content.Context;
import android.content.Intent
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class KeepTime extends Service implements LocationListener {
float minAccuracyMeters = 20.0f;
LocationManager locationManager;
int index = 0;
int maxAmountOfTries = 5;
Timer timer;
boolean currentlyListening = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Service started..");
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if(!isLocationEnabled()){
System.out.println("Location service is not active. Stopping self.");
Toast.makeText(this, "Location service is not active. Stopping self.", Toast.LENGTH_SHORT).show();
this.stopSelf();
return 0;
}
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (currentlyListening) {
} else {
setListener();
}
}
}, 0, 1000 * 60 * 10);
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
mll.removeListener();
mll.cancelTimer();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
System.out.println("Service destroyed..");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private boolean isLocationEnabled() {
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
private void setListener()
{
System.out.println("Set listener called..");
try {
System.out.println("About to set listeners");
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
System.out.println("Location listeners set..");
currentlyListening = true;
}catch(SecurityException e){
System.out.println("Security exception. "+e);
}
}
public void removeListener() {
try {
locationManager.removeUpdates(this);
System.out.println("Removed updates..");
currentlyListening = false;
} catch (SecurityException se) {
System.out.println("Security exception: " + se);
}
}
@Override
public void onLocationChanged(Location location) {
System.out.println("Location changed..");
double longitudeNetwork = location.getLongitude();
double latitudeNetwork = location.getLatitude();
double accuracy = location.getAccuracy();
if(accuracy < minAccuracyMeters || index > maxAmountOfTries) {
System.out.println("Accuracy is less than " + minAccuracyMeters + " Recording..");
System.out.println(longitudeNetwork+ " "+latitudeNetwork+ " "+accuracy);
removeListener();
}
else{
System.out.println("Accuracy was not good enough. Still recorded location.");
}
index++;
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
System.out.println("Status changed");
}
@Override
public void onProviderEnabled(String provider) {
System.out.println("Provider enabled.");
}
@Override
public void onProviderDisabled(String provider) {
System.out.println("Provider disabled.");
}
}
Every 10 minutes I want the location to be printed out when it reaches a certain accuracy or after a certain amount of time. But it throws and exception. Here is the exception:
FATAL EXCEPTION: Timer-0
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I have tried calling the prepare but it just causes more havoc. Any ideas how to achieve what I am after?