Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Get Location Using AsyncTask

I am pulling my hair out with trying to find a good solution to this problem. I made my app so it finds my location. It seems overly complicated but easy enough. However following googles recommendations I am now trying to run this code as an Async task so it doesn't tie up the UI. However I can't even figure out how to get the code to compile never mind actually run. The error is that locationManager cannot be resolved when I reference it to remove the listeners. I have tried using the code posted on here Android find GPS location once, show loading dialog. However in this example currentLocation doesn't seemed to be referenced to anything and I ran into problems trying to sort that out. I have wasted nearly a full day trying to sort this problem so I would really appreciate if somebody can point me in the right direction.

private class LocationControl extends AsyncTask<Context, Void, Location> {
    public Location alocation;
    private LocatoinManager locationManager;

    @Override
    public Location doInBackground(Context... params) {
         locationManager = (LocationManager) params[0].getSystemService(Context.LOCATION_SERVICE);        
          locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, locationListener);
        return alocation;
    }

    public LocationListener locationListener = new LocationListener() {

            public void onStatusChanged(String provider, int status, Bundle extras) {}
            public void onProviderEnabled(String provider) {}
            public void onProviderDisabled(String provider) {}

            public void onLocationChanged(android.location.Location mlocation) {
                saveLocation(mlocation);
                locationManager.removeUpdates(locationListener);
            }
    };  

    void saveLocation(android.location.Location location){
        alocation = location;   
    }

    @Override
    protected void onPostExecute(Location result) {
        useLocation(result);
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        dialog.show(WasserSportLotse.this, " ", "Finding location...");

        super.onPreExecute();
    }
}   

So I changed the code with your recommendations and it now compiles. I have update the code on here to represent what I am running. I am getting a runtime error when the locationManager requestsLocationUpdates. Here is the logCat. Any Ideas?

04-15 14:57:56.742: ERROR/AndroidRuntime(18328): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
04-15 14:57:56.942: ERROR/AndroidRuntime(18328): java.lang.RuntimeException: An error occured while executing doInBackground()
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask.run(FutureTask.java:122)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.lang.Thread.run(Thread.java:1060)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.Handler.<init>(Handler.java:121)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:128)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:126)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:697)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:619)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:62)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:1)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     ... 4 more
04-15 14:58:23.451: ERROR/AndroidRuntime(18356): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
04-15 14:58:23.642: ERROR/AndroidRuntime(18356): java.lang.RuntimeException: An error occured while executing doInBackground()
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask.run(FutureTask.java:122)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.lang.Thread.run(Thread.java:1060)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.Handler.<init>(Handler.java:121)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:128)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:126)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:697)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:619)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:62)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:1)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     ... 4 more
like image 373
jiduvah Avatar asked Apr 15 '11 12:04

jiduvah


2 Answers

public class FastMainActivity extends Activity {

    Button searchBtn = null;
    Intent locatorService = null;
    AlertDialog alertDialog = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        searchBtn = (Button) findViewById(R.id.searchBtn);

        searchBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                if (!startService()) {
                    CreateAlert("Error!", "Service Cannot be started");
                } else {
                    Toast.makeText(FastMainActivity.this, "Service Started",
                            Toast.LENGTH_LONG).show();
                }

            }
        });

    }

    public boolean stopService() {
        if (this.locatorService != null) {
            this.locatorService = null;
        }
        return true;
    }

    public boolean startService() {
        try {
            // this.locatorService= new
            // Intent(FastMainActivity.this,LocatorService.class);
            // startService(this.locatorService);

            FetchCordinates fetchCordinates = new FetchCordinates();
            fetchCordinates.execute();
            return true;
        } catch (Exception error) {
            return false;
        }

    }

    public AlertDialog CreateAlert(String title, String message) {
        AlertDialog alert = new AlertDialog.Builder(this).create();

        alert.setTitle(title);

        alert.setMessage(message);

        return alert;

    }

    public class FetchCordinates extends AsyncTask<String, Integer, String> {
        ProgressDialog progDailog = null;

        public double lati = 0.0;
        public double longi = 0.0;

        public LocationManager mLocationManager;
        public VeggsterLocationListener mVeggsterLocationListener;

        @Override
        protected void onPreExecute() {
            mVeggsterLocationListener = new VeggsterLocationListener();
            mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, 0, 0,
                    mVeggsterLocationListener);

            progDailog = new ProgressDialog(FastMainActivity.this);
            progDailog.setOnCancelListener(new OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    FetchCordinates.this.cancel(true);
                }
            });
            progDailog.setMessage("Loading...");
            progDailog.setIndeterminate(true);
            progDailog.setCancelable(true);
            progDailog.show();

        }

        @Override
        protected void onCancelled(){
            System.out.println("Cancelled by user!");
            progDialog.dismiss();
            mLocationManager.removeUpdates(mVeggsterLocationListener);
        }

        @Override
        protected void onPostExecute(String result) {
            progDailog.dismiss();

            Toast.makeText(FastMainActivity.this,
                    "LATITUDE :" + lati + " LONGITUDE :" + longi,
                    Toast.LENGTH_LONG).show();
        }

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub

            while (this.lati == 0.0) {

            }
            return null;
        }

        public class VeggsterLocationListener implements LocationListener {

            @Override
            public void onLocationChanged(Location location) {

                int lat = (int) location.getLatitude(); // * 1E6);
                int log = (int) location.getLongitude(); // * 1E6);
                int acc = (int) (location.getAccuracy());

                String info = location.getProvider();
                try {

                    // LocatorService.myLatitude=location.getLatitude();

                    // LocatorService.myLongitude=location.getLongitude();

                    lati = location.getLatitude();
                    longi = location.getLongitude();

                } catch (Exception e) {
                    // progDailog.dismiss();
                    // Toast.makeText(getApplicationContext(),"Unable to get Location"
                    // , Toast.LENGTH_LONG).show();
                }

            }

            @Override
            public void onProviderDisabled(String provider) {
                Log.i("OnProviderDisabled", "OnProviderDisabled");
            }

            @Override
            public void onProviderEnabled(String provider) {
                Log.i("onProviderEnabled", "onProviderEnabled");
            }

            @Override
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
                Log.i("onStatusChanged", "onStatusChanged");

            }

        }

    }

}
like image 197
SALMAN Avatar answered Oct 24 '22 08:10

SALMAN


Just add Looper.prepare() before calling locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, locationListener); Remember to call Looper.loop() after.

like image 4
jibysthomas Avatar answered Oct 24 '22 08:10

jibysthomas