I have tried to get this code sorted couple of times. Here’s the scenario I have tried so far…
Scenario:
Once the activity is started I want to get the coordinates (long & lat) based on network/gps provider. This should run in background and it should keep checking until long & lat is not null or “0.0”. Thus, I have tried the following code with AsyncTask and thereby using LocationListener in doInBackground method.
Source Code:
public class GetLocation extends AsyncTask<String, String, String>
{
private myTest test;
boolean running =true;
private Context cont;
String addressString;
public GetLocation(myTest fr, Context contxt)
{
test = fr;
cont = contxt;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result)
{
test.GetContent();
}
#Override
protected String doInBackground(String... params) {
Looper.myLooper().prepare();
LocationManager locationManager;
locationManager = (LocationManager) cont
.getSystemService(Context.LOCATION_SERVICE);
Criteria crta = new Criteria();
crta.setAccuracy(Criteria.ACCURACY_FINE);
crta.setAltitudeRequired(false);
crta.setBearingRequired(false);
crta.setCostAllowed(true);
crta.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(crta, true);
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
locationManager.requestLocationUpdates(provider, 0, 0,
locationListener);
Looper.loop();
return addressString;
}
private void updateWithNewLocation(Location location) {
Constants.lat = Double.toString(location.getLatitude());
Constants.long = Double.toString(location.getLongitude());
}
}
Problem:
However, I also know that Looper’s can help to keep the thread active. I want to be able to get valid coordinates and this should loop until its received. How do i call to get the locations over and over again until valid one's are received? (I could put conditions within the loops i have provided but im not aware as to how and what methods i should call to achieve this). Please provide a code snippet if possible.
Cheers!
You have implemented this wrong. There is no need to create the AsyncTask. The LocationManager will asynchronously fetch locations for you and deliver them on your LocationListener.onLocationChanged. Once you get a proper Location you can call LocationManager.removeUpdates() and this will stop for further delivery of Locations.
Do not use AsyncTask for this. You just registered the LocationManager that is listen by LocationListener and use progressbar for that. Once call LocationListner.onLocationChanged try to get Lat and Long and dismiss the progress bar. OnLocationChanged will be call at you move your device for a short distance.
Related
I have an AsyncTask class that needs to get user's location when this AsyncTask is called.
The idea is to check if location service is enabled or not, if not, the location service toggle will popup for user to turn it on, then it will go back to the task to continue getting the location and finish the job.
However, the code below show NullPointerException on the line lat = location.getLatitude(); near the end of onPreExecute(). They said because getLastKnownLocation gets nothing as it's just been turned on a moment ago, then how can I get the location right after the location service has been turned on?
LocationManager locationManager;
LocationListener locationListener;
double lat;
double longi;
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
location = new Location(LocationManager.NETWORK_PROVIDER);
locationManager = (LocationManager) context.getSystemService(context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
//I copy the part below from the internet but seems like "onProviderDisabled" and "onLocationChanged" were never be called
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Log.v("GPS CHECKKKKKKK",location.getLatitude()+"_"+location.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
};
locationManager.requestLocationUpdates("gps", 500, 0, locationListener);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,5000,0, locationListener);
lat = location.getLatitude();
longi= location.getLongitude();
Log.v("GPS Cord CHECK",lat+"_"+longi);
}
#Override
protected String doInBackground(final Checkout_Package... params) {
//Doing the job that needs lat and longi value!
}
Thank you for your time!
You cannot create and put a location listener in onPreExecute() because the onChanged handlers will only be invoked much later when onPostExecute or even your AsyncTask has finished.
What you should do instead is start an AsyncTask in that location changed handler.
So in onLocationChanged().
With greenapps's suggest I figured it out. I put the code into the button that call the AsyncTask
checkout_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LocationManager locationManager;
LocationListener locationListener;
gotit = false; //Boolean to start the AsyncTask only once.
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Log.v("GPS CHECKKKKKKK",location.getLatitude()+"_"+location.getLongitude());
lat = location.getLatitude();
longi = location.getLongitude();
if (gotit == false) {
new Checkout_Async(Checkout.this, listener).execute(new Checkout_Package(user, product_all, getTotalCost(product_all), fee, getTotalCost(product_all) + fee, lat, longi));
gotit = true;
pd.dismiss();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
pd=ProgressDialog.show(Checkout.this,"",getResources().getString(R.string.please_wait),false);
locationManager.requestLocationUpdates("gps",50,0,locationListener);
}
});
Now it works. Thank you!
all
I have carefully read many related Q&A in this site, but nothing help me. Here is my code, it works fine with GPS on, but went wrong once i turn off the GPS.
/**
*
* #author Jimmy Chiang
*
*/
public class GetLocationTask extends AsyncTask<Context, Void, Location> {
private OnLocationListener[] mGpsListeners;
private Location location;
private LocationListener locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location lo) {
location = lo;
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
};
public interface OnLocationListener {
public void onLocationGot(Location location);
}
public GetLocationTask setOnLocationListener(
OnLocationListener... listeners) {
mGpsListeners = listeners;
return this;
}
#Override
protected Location doInBackground(Context... params) {
LocationManager locationManager = (LocationManager) params[0]
.getSystemService(Context.LOCATION_SERVICE);
String provider = LocationManager.NETWORK_PROVIDER;
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
provider = LocationManager.GPS_PROVIDER;
}
location = locationManager.getLastKnownLocation(provider);
while (location == null) {
locationManager.requestLocationUpdates(provider, 1000, 1,locationListener);
}
return location;
}
#Override
protected void onPostExecute(Location location) {
for (OnLocationListener listener : mGpsListeners) {
listener.onLocationGot(location);
}
}
}
The exception shows:
can't create handler inside thread that has not called
looper.prepare()
Some posts show that the problem should be call someting in UI Thread, but i can't find any of this. Thanks so much if you know what's going on~
change
locationManager.requestLocationUpdates(provider, 1000, 1,locationListener);
with
locationManager.requestLocationUpdates(provider, 1000, 1,locationListener, Looper.getMainLooper());
as stand in the docs
Looper.getMainLooper()
Returns the application's main looper, which lives in the main thread
of the
application.
the looper arguments of requestLocationUpdate is a Looper object whose message queue will be used to implement the callback mechanism, or null to make callbacks on the calling thread.
If you want the AsyncTask to be the one that will receive the messages you have to use
Looper.myLooper().prepare();
locationManager.requestLocationUpdates(provider, 1000, 1,locationListener, Looper.myLooper());
I use the following code to get Current Location from a Network provider in my application:
LocationManager mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean network_enabled = mgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(network_enabled){
Location location = mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
But it gives a location approximately 300-700 meters away from my actual location.
This is expected from a Network provider. But the problem is:
with only this Network provider enabled, and no GPS, I openned Foursquare
application where it shows my current location exactly where I am. Now
when I come back to my application, it shows the accurate current
location or say the same location which Foursquare showed.
Same thing happens with Google apps like Navigator, Maps etc..,
How can this be done? How are other apps able to get the exact location, based on just the Network provider?
Complete Code:
public class MyLocationActivity extends Activity implements LocationListener {
private LocationManager mgr;
private String best;
Location location;
public static double myLocationLatitude;
public static double myLocationLongitude;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
best = mgr.getBestProvider(criteria, true);
location = mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
dumpLocation(location);
}
public void onLocationChanged(Location location) {
dumpLocation(location);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 10, this);
}
private void dumpLocation(Location l) {
if (l != null){
myLocationLatitude = l.getLatitude();
myLocationLongitude = l.getLongitude();
}
}
}
Thank You
You are getting just the last known location. You should request location updates from the LocationManager. Use LocationManager.getLocationUpdates.
On your LocationListener on the onLocationChanged(Location location) method, you can check on the Location object, how accurate this location is, like this :
float accuracy=location.getAccuracy();
then, if this Location is accurate enough for you, you can stop receiving location updates from the LocationManager using removeUpdates() , and use the received Location. If the Location is not accurate enough, you can wait for a more precise Location, and stop the updates latter on.
I'm kinda lost here: In my main activity, I register a LocationManager and connect it to a LocationListener to use myLocation.getLatitude() and such.
Now I need to use the Location- methods from another class.
I can't use those object from another class because I cant intantiate the main activity.
I can't use getters to pass the L.Manager or L.Listener around, because those are non- static again.
So, in general, how do i access objects that I created in the main activity?
Any hints on how to organize this better? Is the LocationListener class within the main activity class a stupid thing to do in general?
public class URNavActivity extends Activity
{
public LocationManager mlocManager;
public LocationListener mlocListener;
...
}
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
actVar=this;
initGraph();
setMap();
gpsEnable();
initMyLocation();
getItems();
initOverlay();
}
public void gpsEnable ()
{
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
myMap.getController().setCenter(new GeoPoint(lati, longi));
}
First and foremost your LocationListener should not be part of an activity. Activities have a clearly defined lifecycle and can come into being, and be destroyed, by the Android framework on an as-needed basis. Therefore the instance variables of your Activity will need to be re-initialised in your activity's onResume() method, making them completely unsuitable for long-term storage.
So. Start by creating a sticky service to manage the starting and stopping of location updates. Being sticky means that the service instance hangs around between invocations and therefore you can reliably use instance variables and know that they will retain their values until the service is terminated. This service should also implement the LocationListener interface, and now it can store the Location notified to it when onLocationChanged is invoked:
public class LocationService extends Service implements LocationListener {
private LocationManager locationManager;
private Location location;
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Logging.i(CLAZZ, "onHandleIntent", "invoked");
if (intent.getAction().equals("startListening")) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else {
if (intent.getAction().equals("stopListening")) {
locationManager.removeUpdates(this);
locationManager = null;
}
}
return START_STICKY;
}
#Override
public IBinder onBind(final Intent intent) {
return null;
}
public void onLocationChanged(final Location location) {
this.location = location;
// TODO this is where you'd do something like context.sendBroadcast()
}
public void onProviderDisabled(final String provider) {
}
public void onProviderEnabled(final String provider) {
}
public void onStatusChanged(final String arg0, final int arg1, final Bundle arg2) {
}
}
Now you have a service you can start and stop the location updates as you need them. This also allows you to continue to receive and process location changes even when your application is not in the foreground, if that is what you want.
You now have two choices on how to make that Location information available: Use context.sendBroadcast() to propagate the new Location to (for example) an activity, or use the bound service approach to allow other classes to invoke the exposed API and obtain the Location. See http://developer.android.com/guide/topics/fundamentals/bound-services.html for more details on creating a bound service.
Note that there are many other aspects to listening for location updates that I have not included here, for the sake of clarity.
I would offer two elegant ways to access your object from anywhere:
use a Singleton design pattern
use ProjectApp class. This class can be accessed from any activity simply by calling getApplication().
ProjectApp app = (ProjectApp)getApplication();
I used a combination of the two:
public class MyApp extends Application {
private MyLocation mMyLocation;
#Override
public void onCreate() {
super.onCreate();
mMyLocation = new MyLocation();
mMyLocation.getLocation(this, GlobalData.getInstance(), true);
}
}
You can see that GlobalData is a singleton class that implements LocationResult interface, meaning that it will send the updated location to this object.
When I need to get the updated location, I take it from GlobalData.
Here is MyLocation class implementation (I used some code from here and made some changes:
package com.pinhassi.android.utilslib;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class MyLocation {
private Timer timer1;
private LocationManager lm;
private LocationResult locationResult;
private boolean gps_enabled=false;
private boolean network_enabled=false;
private boolean mContinuesUpdates;
private int decimalAccuracy;
/**
* Class constructor
*/
public MyLocation(){
decimalAccuracy = 0;
}
public boolean getLocation(Context context, LocationResult result, boolean continuesUpdates)
{
mContinuesUpdates = continuesUpdates;
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(getDecimalAccurated(location));
if (!mContinuesUpdates)
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(getDecimalAccurated(location));
if (!mContinuesUpdates)
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
#Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(getDecimalAccurated(gps_loc));
else
locationResult.gotLocation(getDecimalAccurated(net_loc));
return;
}
if(gps_loc!=null){
locationResult.gotLocation(getDecimalAccurated(gps_loc));
return;
}
if(net_loc!=null){
locationResult.gotLocation(getDecimalAccurated(net_loc));
return;
}
locationResult.gotLocation(null);
}
}
/**
* called when the GPS returns a location.
* can be called multiple times as the location is updated
*/
public interface LocationResult {
public void gotLocation(Location location);
}
/**
* sets location result accuracy
* #param n number of places after the point. negative value or 0 means not set.
*/
public void setDecimalAccuracy(int n)
{
this.decimalAccuracy = n;
}
private Location getDecimalAccurated(Location location) {
if (decimalAccuracy > 0){
double accuracy = Math.pow(10, this.decimalAccuracy);
int ix;
ix = (int)(location.getLatitude() * accuracy);
location.setLatitude(((double)ix)/accuracy);
ix = (int)(location.getLongitude() * accuracy);
location.setLongitude(((double)ix)/accuracy);
}
return location;
}
}
I'll talk in general since I had the same issue:
How to manage the LocationListener and lit this listener access the activity ..
This was my try :
The Listener :
public class MyLocationListener implements LocationListener{
ProgressDialog dialog;
LocationManager locManager;
Context context;
public MyLocationListener (Context context,ProgressDialog dialog){
this.context = context;
this.dialog = dialog;
}
public void startSearch() {
locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// If the network provider works run it , else try GPS provider
// TODO : what happens if GPS and Network providers are not suuported ??
if(!locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) )
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, this);
else
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
0, this);
dialog = new ProgressDialog(context);
dialog.setTitle("");
dialog.setMessage(context.getString(R.string.pleaseWait));
dialog.setButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
locManager.removeUpdates(MyLocationListener .this);
dialog.dismiss();
return;
}
});
dialog.show();
}
// Location Listener implementation
// read Android doc for more info
// this methods is triggered when new location ( latitiude and longitude ) is found by the system
private void updateWithNewLocation(Location location) {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
//THIS IS MY ACTIVITY
MainActivity mainActivity = (MainActivity) context;
mainActivity.init();
} else {
//this.setSummary( "No location found" );
}
// remove the listener , we don't need it anymore
locManager.removeUpdates(this);
dialog.hide();
}
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider) {
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
init the listener in the MainActivity like this :
ProgressDialog dialog;
.
.
.
new MyLocationListener (this, dialog).startSearch();
I don't know if that help ? but that was my solution ...
Hi I am New to android programming and currently developing an application that uses location manager to get user location and place a marker on a map. i am attempting to use AsyncTask to run the LocationListener and Constantly update the marker when the user location has changed.
this is the class i am working on...
public class IncidentActivity extends MapActivity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.incidentactivity);
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setTraffic(true);
mapController = mapView.getController();
String coordinates[] = {"-26.167004","27.965505"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
geoPoint = new GeoPoint((int)(lat*1E6), (int)(lng*1E6));
mapController.animateTo(geoPoint);
mapController.setZoom(16);
mapView.invalidate();
new MyLocationAsyncTask().execute();
}
private class MyLocationAsyncTask extends AsyncTask<Void, Location, Void> implements LocationListener{
private double latLocation;
private Location l;
//location management variables to track and maintain user location
protected LocationManager locationManager;
protected LocationListener locationListener;
#Override
protected Void doInBackground(Void... arg0) {
Looper.prepare();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, locationListener);
this.publishProgress(l);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Location... values) {
super.onProgressUpdate(values);
}
//this method is never executed i dont know why...?
public void onLocationChanged(Location location) {
if (location != null){
latLocation = location.getLatitude();
Toast.makeText(getBaseContext(), " Your latLocation :" + latLocation, Toast.LENGTH_LONG).show();
//Log.d("Your Location", ""+latLocation);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
}
I've just implemented such AsyncTask:
class GetPositionTask extends AsyncTask<Void, Void, Location> implements LocationListener
{
final long TWO_MINUTES = 2*60*1000;
private Location location;
private LocationManager lm;
protected void onPreExecute()
{
// Configure location manager - I'm using just the network provider in this example
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
nearProgress.setVisibility(View.VISIBLE);
}
protected Location doInBackground(Void... params)
{
// Try to use the last known position
Location lastLocation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// If it's too old, get a new one by location manager
if (System.currentTimeMillis() - lastLocation.getTime() > TWO_MINUTES)
{
while (location == null)
try { Thread.sleep(100); } catch (Exception ex) {}
return location;
}
return lastLocation;
}
protected void onPostExecute(Location location)
{
nearProgress.setVisibility(View.GONE);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
// HERE USE THE LOCATION
}
#Override
public void onLocationChanged(Location newLocation)
{
location = newLocation;
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
From what I have read and tried, you cannot use a looper (which is needed by the locationlistener), inside an ASyncTask. Click Here
Actually it mean the two threading models are not compatible, so you can't
use these together. Looper expects to to own the thread that you associate
it with, while AsyncTask owns the thread it creates for you to run in the
background. They thus conflict with each other, and can't be used together.
Dianne Hackborn suggested using a HandlerThread, but I succeeded in getting mine to work inside of an IntentService. I will admit that my code is still a bit of a hack.