使用Geocoder和Android Google Maps API V2获取纬度和经度

23

我正在使用适用于Android的Google Maps API v2,它可以正常工作。

然而,我在尝试使用地理编码器获取地址的经度和纬度时一直没有成功。

它是否已经从v2版中更改了这种方式?

我正在使用传统的代码。

Geocoder gc = new Geocoder(context);
//...
  List<Address> list = gc.getFromLocationName("1600 Amphitheatre Parkway, Mountain View, CA", 1);

  Address address = list.get(0);

  double lat = address.getLatitude();
  double lng = address.getLongitude();
//...

始终返回强制关闭,并且日志没有解决任何问题。在使用try / catch块时,打开地图但始终显示相同位置。需要使用互联网权限,我已将COARSE_LOCATION也包含在项目中。我尝试过这里和其他网站上的各种代码,但没有成功。

提前致谢。


你是否设置了android.permission.INTERNET权限? - bizzehdee
1
你说日志没什么用,但也许你应该把它包含进去(我敢打赌它实际上会提供一些有关问题的线索)。 - Booger
我已经拥有了互联网权限和日志,谢谢:03-29 22:25:10.922: E/AndroidRuntime(4359): java.lang.RuntimeException: 无法启动组件信息的活动ComponentInfo{blue.ninja.master/blue.ninja.master.Hola}: java.lang.NullPointerException 03-29 22:25:10.922: E/AndroidRuntime(4359): at android.app.ActivityThread.access$600(ActivityThread.java:130) 03-29 22:25:10.922: E/AndroidRuntime(4359): at android.app.ActivityThread 03-29 22:25:10.922: E/AndroidRuntime(4359): 由于java.lang.NullPointerException,在blue.ninja.master.Hola.onCreate(Hola.java:50)处发生错误。 - Sergio76
5个回答

54

尝试使用此示例网址解决问题:

http://maps.google.com/maps/api/geocode/json?address=mumbai&sensor=false

该网址以json格式返回地址纬度/经度信息。

private class DataLongOperationAsynchTask extends AsyncTask<String, Void, String[]> {
   ProgressDialog dialog = new ProgressDialog(MainActivity.this);
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setMessage("Please wait...");
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    @Override
    protected String[] doInBackground(String... params) {
        String response;
        try {
            response = getLatLongByURL("http://maps.google.com/maps/api/geocode/json?address=mumbai&sensor=false");
            Log.d("response",""+response);
            return new String[]{response};
        } catch (Exception e) {
            return new String[]{"error"};
        }
    }

    @Override
    protected void onPostExecute(String... result) {
        try {
            JSONObject jsonObject = new JSONObject(result[0]);

            double lng = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lng");

            double lat = ((JSONArray)jsonObject.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lat");

            Log.d("latitude", "" + lat);
            Log.d("longitude", "" + lng);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if (dialog.isShowing()) {
            dialog.dismiss();
        }
    }
}


public String getLatLongByURL(String requestURL) {
    URL url;
    String response = "";
    try {
        url = new URL(requestURL);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");
        conn.setDoOutput(true);
        int responseCode = conn.getResponseCode();

        if (responseCode == HttpsURLConnection.HTTP_OK) {
            String line;
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while ((line = br.readLine()) != null) {
                response += line;
            }
        } else {
            response = "";
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return response;
}

希望这能对你有所帮助。


@AmolSawant96Kuli,这个解决方案工作正常吗?我问你是因为我发现地理编码器不太好用。 - Umberto
你能更新一下这段代码吗?它似乎使用了被弃用的HttpClient,在Android 6上已经不可用了。 - android developer
@AmolSawant96Kuli 谢谢。请问,这样使用 Google 的网站真的可以吗?不需要为它们注册或做些什么吗? - android developer
我认为你应该使用Uri.Builder而不是常量字符串,这样它就可以根据需要自动替换字符。 - android developer
这段代码对你还有效吗?我得到了一个网络超时和0个结果。这个解决方案的替代方案非常丑陋,所以我真的希望这仍然对我有用。 - John Ward
显示剩余3条评论

8

试试这个。

private void getLatLongFromAddress(String address)
{
    double lat= 0.0, lng= 0.0;

    Geocoder geoCoder = new Geocoder(this, Locale.getDefault());    
    try 
    {
        List<Address> addresses = geoCoder.getFromLocationName(address , 1);
        if (addresses.size() > 0) 
        {            
            GeoPoint p = new GeoPoint(
                    (int) (addresses.get(0).getLatitude() * 1E6), 
                    (int) (addresses.get(0).getLongitude() * 1E6));

            lat=p.getLatitudeE6()/1E6;
            lng=p.getLongitudeE6()/1E6;

            Log.d("Latitude", ""+lat);
            Log.d("Longitude", ""+lng);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

似乎问题是 Android 的一个 bug:http://code.google.com/p/android/issues/detail?id=8816 ...我不知道该如何修复它 :((( - Sergio76
@MiguelC:你能通过地址找到经纬度吗?我也遇到了同样的问题。 - Divya Motiwala
我发现对于我来说,结果总是在错误的国家(即使我在地址中包括了国家)。 - row1

2

由于HttpClient已经被弃用,您可以尝试使用Asynctask来运行以下代码(请注意我们需要将地址编码为URL):

public class GeoCoding extends AsyncTask<Void, Void, Void> {
    private String address;
    private static final String TAG = GeoCoding.class.getSimpleName();
    JSONObject jsonObj;
    String URL;
    private String Address1 = "", Address2 = "", City = "", State = "", Country = "", County = "", PIN = "", Area="";
    private  double latitude, longitude;
    HttpURLConnection connection;
    BufferedReader br;
    StringBuilder sb ;

    public GeoCoding(String address){
        this.address = address;
    }

    public String getArea(){
        return Area;
    }

    public void getAddress() {
        Address1 = "";
        Address2 = "";
        City = "";
        State = "";
        Country = "";
        County = "";
        PIN = "";
        Area ="";

        try {

            String Status = jsonObj.getString("status");
            if (Status.equalsIgnoreCase("OK")) {
                JSONArray Results = jsonObj.getJSONArray("results");
                JSONObject zero = Results.getJSONObject(0);
                JSONArray address_components = zero.getJSONArray("address_components");

                for (int i = 0; i < address_components.length(); i++) {
                    JSONObject zero2 = address_components.getJSONObject(i);
                    String long_name = zero2.getString("long_name");
                    JSONArray mtypes = zero2.getJSONArray("types");
                    String Type = mtypes.getString(0);

                    if (! TextUtils.isEmpty(long_name) || !long_name.equals(null) || long_name.length() > 0 || !long_name.equals("")) {
                        if (Type.equalsIgnoreCase("street_number")) {
                            Address1 = long_name + " ";
                        } else if (Type.equalsIgnoreCase("route")) {
                            Address1 = Address1 + long_name;
                        } else if (Type.equalsIgnoreCase("sublocality")) {
                            Address2 = long_name;
                        } else if (Type.equalsIgnoreCase("locality")) {
                            City = long_name;
                        } else if (Type.equalsIgnoreCase("administrative_area_level_2")) {
                            County = long_name;
                        } else if (Type.equalsIgnoreCase("administrative_area_level_1")) {
                            State = long_name;
                        } else if (Type.equalsIgnoreCase("country")) {
                            Country = long_name;
                        } else if (Type.equalsIgnoreCase("postal_code")) {
                            PIN = long_name;
                        }else if( Type.equalsIgnoreCase("neighborhood")){
                            Area = long_name;
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void getGeoPoint(){
        try{
             longitude = ((JSONArray)jsonObj.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lng");
            latitude = ((JSONArray)jsonObj.get("results")).getJSONObject(0)
                    .getJSONObject("geometry").getJSONObject("location")
                    .getDouble("lat");

        }catch (Exception e){
            e.printStackTrace();
        }

    }


    @Override
    protected Void doInBackground(Void... params)  {
        try {
            StringBuilder urlStringBuilder = new StringBuilder("http://maps.google.com/maps/api/geocode/json");
            urlStringBuilder.append("?address=" + URLEncoder.encode(address, "utf8"));
            urlStringBuilder.append("&sensor=false");
            URL = urlStringBuilder.toString();
            Log.d(TAG, "URL: " + URL);

            URL url = new URL(URL);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            connection.connect();
            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb = sb.append(line + "\n");
            }
        }catch (Exception e){e.printStackTrace(); }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        try {
            Log.d(TAG, "response code: " + connection.getResponseCode());
            jsonObj = new JSONObject(sb.toString());
            Log.d(TAG, "JSON obj: " + jsonObj);
            getAddress();
            Log.d(TAG, "area is: " + getArea());
            getGeoPoint();
            Log.d("latitude", "" + latitude);
            Log.d("longitude", "" + longitude);


            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onPostExecute(aVoid);
    }
}

0
一个对我有效的简单纠正方法是在设备上启用互联网连接。Pxaml 的建议。

-11

通过这个简单的代码,您可以获取当前位置的纬度和经度

GPS_Location mGPS = new GPS_Location(MyApplication.getAppContext());

    if (mGPS.canGetLocation) {

        mLat = mGPS.getLatitude();
        mLong = mGPS.getLongitude();

    } else {
        System.out.println("cannot find");
    }

你必须在你的应用程序中添加 GPS 以及其他权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接