I am making an android app where I am trying to get location using location manager and then I push that location to a server. When I try to do this I am getting the following error.
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:223)
at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:223)
at android.location.LocationManager.wrapListener(LocationManager.java:851)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:864)
at android.location.LocationManager.requestLocationUpdates(LocationManager.java:459)
at com.pickingo.fe.services.gps.AppLocationService.getLocation(AppLocationService.java:30)
at com.pickingo.fe.gps.CurrentLocationPusher.run(CurrentLocationPusher.java:60)
at java.lang.Thread.run(Thread.java:818)
This is my appLocationService
public class AppLocationService extends Service implements LocationListener {
protected LocationManager locationManager;
Location location;
private static final long MIN_DISTANCE_FOR_UPDATE = 50;
private static final long MIN_TIME_FOR_UPDATE = 1000*60*2;
public AppLocationService(Context context) {
locationManager = (LocationManager) context
.getSystemService(LOCATION_SERVICE);
}
public Location getLocation(String provider) {
if (locationManager.isProviderEnabled(provider)) {
locationManager.requestLocationUpdates(provider,
MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(provider);
return location;
}
}
return null;
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
This is the code I use to push the location after getting the location from the LocationManager.
public class CurrentLocationPusher implements Runnable {
private static CurrentLocationPusher _singleInstance;
private CurrentLocationPusher() {
this.apiClient = ApiClient.getInstance();
this.appLocationService = new AppLocationService(appContext);
this.runningThread = new Thread(this);
}
public static CurrentLocationPusher getInstance() {
if (_singleInstance == null)
synchronized (CurrentLocationPusher.class) {
if (_singleInstance == null)
_singleInstance = new CurrentLocationPusher();
}
return _singleInstance;
}
private boolean isStopThread = false;
public static final long ONE_MINUTE = 60 * 1000;
private static Context appContext;
private AppLocationService appLocationService;
private ApiClient apiClient;
private Thread runningThread;
public static void init(Context applicationContext) {
appContext = applicationContext;
}
@Override
public void run() {
Location location = appLocationService
.getLocation(LocationManager.GPS_PROVIDER);
while (!isStopThread) {
try {
if (location != null)
if (CommonUtils.isActiveToInternet(appContext))
apiClient.getApi(appContext).pushLocation(String.valueOf(location.getLatitude()),
String.valueOf(location.getLongitude()),String.valueOf(System.currentTimeMillis()),
String.valueOf(location.getAccuracy()));
Thread.sleep(ONE_MINUTE);
} catch (InterruptedException e) {
} catch (Exception e) {
Log.e(PickingoConstant.TAG, "error" + e.getMessage());
}
}
}
public void startPushingLocation() {
if (this.runningThread.getState() == Thread.State.NEW) {
runningThread.start();
isStopThread = false;
} else if (this.runningThread.getState() == Thread.State.TERMINATED) {
(runningThread = new Thread(this)).start();
isStopThread = false;
} else if (this.runningThread.getState() == Thread.State.RUNNABLE) {
return;
}
}
public void stopPushingLocation() {
isStopThread = true;
}
}
I am getting error at the following line in CurrentLocationPusher
.getLocation(LocationManager.GPS_PROVIDER);
If someone could give a hint or some assistance I would really appreciate it. Thanks in advance !!
As pointed out by Michael adding this code at starting of my run() method worked.
if (Looper.myLooper() == null) {
Looper.prepare();
}