使用 AsyncTask 在后台查找城市名称

Find name of city in background with AsyncTask

我的目标是使用来自 LocationListener 的坐标获取用户所在城市的名称,并将其与 Google 的地图 API 匹配,在后台使用 AsyncTask。

当我从 MainActivity (onCreate) 调用 CityFinder 时,没有任何反应。我没有看到来自 onPreExecute 的任何日志。

我需要做什么来解决这个问题?

CityFinder 异步任务

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);
    }
}

您在创建 AsyncTask 后错过了 execute 调用。有关示例,请参见此文档: https://developer.android.com/reference/android/os/AsyncTask.html

由于您的 doInBackground 调用不使用 params,您可以简单地 运行 使用:

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