Search code examples
androidgoogle-maps-api-3android-asynctaskcity

Find name of city in background with AsyncTask


My goal is to get the name of the city the user is in using the coordinates from the LocationListener and matching that with Google's Maps API, in the background with AsyncTask.

When I call CityFinder from my MainActivity (onCreate), nothing is happening. I do not see any logs from onPreExecute.

What do I need to do to fix this?

CityFinder AsyncTask

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;

import org.json.JSONException;
import org.json.JSONObject;

import static android.support.v4.app.ActivityCompat.requestPermissions;
import static com.android.volley.toolbox.Volley.*;

public class CityFinder extends AsyncTask<Void, Void, Void> {

    private Activity activity;
    private ProgressDialog progressDialog;
    private String googleMapsGeoURL = "http://maps.googleapis.com/maps/api/geocode/json?latlng=";
    private LocationManager locationManager;
    private LocationListener locationListener;
    protected String cityName;

    public CityFinder(Activity activity, LocationManager locationManager, LocationListener locationListener) {
        this.activity = activity;
        this.locationManager = locationManager;
        this.locationListener = locationListener;
        this.progressDialog = new ProgressDialog(this.activity);
    }

    protected void onPreExecute() {
        Log.v("CityFinder", "onPreExecute");
        progressDialog.setMessage("Getting your city's name...");
        progressDialog.show();
        progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            public void onCancel(DialogInterface arg0) {
                CityFinder.this.cancel(true);
            }
        });
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {
            this.locationManager = (LocationManager) this.activity.getSystemService(this.activity.LOCATION_SERVICE);
            this.locationListener = new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    googleMapsGeoURL += location.getLatitude() + "," + location.getLongitude();
                    Log.v("CityFinder", googleMapsGeoURL);
                    final RequestQueue requestQueue = newRequestQueue(activity);
                    JsonObjectRequest request = new JsonObjectRequest(googleMapsGeoURL, null,
                            new Response.Listener<JSONObject>() {
                                @Override
                                public void onResponse(JSONObject response) {
                                    try {
                                        cityName =
                                                response.getJSONArray("results").getJSONObject(0).getString("formatted_address");
                                    } catch (JSONException jex) {
                                    }
                                }
                            }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                        }
                    });
                    requestQueue.add(request);
                }

                @Override
                public void onStatusChanged(String s, int i, Bundle bundle) {
                }

                @Override
                public void onProviderEnabled(String s) {
                }

                @Override
                public void onProviderDisabled(String s) {
                    activity.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            };
            locationManager.requestLocationUpdates("gps", 1000, 0, locationListener);
        } catch (SecurityException se) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(this.activity, new String[]{
                        android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION,
                        android.Manifest.permission.INTERNET}, 9000);
                return null;
            } else {
            }
            Toast.makeText(activity, se.getLocalizedMessage(), Toast.LENGTH_LONG).show();
        }
        return null;
    }

    protected void onPostExecute(Void v) {
        this.progressDialog.setMessage("Your city name has been found: " + this.cityName);
    }
}

Solution

  • You're missing the execute call after creating your AsyncTask. See this doc for an example: https://developer.android.com/reference/android/os/AsyncTask.html

    Since your doInBackground call doesn't use params, you can simply run it with:

    new CityFinder(this, this.locationManager, this.locationListener).execute();