繁体   English   中英

Android Geocoder在某些设备上表现不同

[英]Android Geocoder behaves different on some devices

我有下面的代码,它在某些设备上运行得很好,而在其他设备中,函数getFromLocationName返回一个大小为0的列表。

例如,在Nexus 6p它返回正确的结果,在Meizu MX5它返回一个大小为0的列表。

我拥有相同的权限和两个设备的GPS启用。 Nexus 6p上的Android版本为7.1.2,而Meizu MX5上的Android版本为5.1

  Geocoder geocoder = new Geocoder(context);
  List<Address> addresses = geocoder.getFromLocationName(place, 3);

备注

  1. place是用户输入的位置(String)。
  2. Geocoder来自android.location.Geocoder;

为什么差异呢? 它与设备上的Android版本有关吗?

Android中的Geocoder实际上在所有设备上都没有相同的行为。 我用以下设备测试了Geocoder:

  • 三星(Android 4.4和5.1)
  • 联想(Android 5.0)
  • Vivo(Android 6.0.1)
  • Andromax(Android 5.1.1)
  • 小米(Android 5.1)

所有设备返回列表但小米,它返回零列表。 所以,我们不能依赖Geocoder。 解决方案是使用Google Geocoding API创建我们自己的Geocoder实现,并在列表返回0时使用它。

这里是Geocoder的实现(我发现它来自SO,但不记得来源)可以像使用Geocoder一样繁琐地使用:

import android.location.Address;
import android.util.Log;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MyGeocoder {

  public static final String TAG = MyGeocoder.class.getSimpleName();

  static OkHttpClient client = new OkHttpClient();

  public static List<Address> getFromLocation(double lat, double lng, int maxResult) {

    String address = String.format(Locale.US,
        "https://maps.googleapis.com/maps/api/geocode/json?latlng=%1$f,%2$f&sensor=false&language="
            + Locale.getDefault().getCountry(), lat, lng);
    Log.d(TAG, "address = " + address);
    Log.d(TAG, "Locale.getDefault().getCountry() = " + Locale.getDefault().getCountry());

    return getAddress(address, maxResult);

  }

  public static List<Address> getFromLocationName(String locationName, int maxResults)  {

    String address = null;
    try {
      address = "https://maps.google.com/maps/api/geocode/json?address=" + URLEncoder.encode(locationName,
          "UTF-8") + "&ka&sensor=false";
      return getAddress(address, maxResults);
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return null;
  }

  private static List<Address> getAddress(String url, int maxResult) {
    List<Address> retList = null;

    Request request = new Request.Builder().url(url)
        .header("User-Agent", "OkHttp Headers.java")
        .addHeader("Accept", "application/json; q=0.5")
        .build();
    try {
      Response response = client.newCall(request).execute();
      String responseStr = response.body().string();
      JSONObject jsonObject = new JSONObject(responseStr);

      retList = new ArrayList<Address>();

      if ("OK".equalsIgnoreCase(jsonObject.getString("status"))) {
        JSONArray results = jsonObject.getJSONArray("results");
        if (results.length() > 0) {
          for (int i = 0; i < results.length() && i < maxResult; i++) {
            JSONObject result = results.getJSONObject(i);
            Address addr = new Address(Locale.getDefault());

            JSONArray components = result.getJSONArray("address_components");
            String streetNumber = "";
            String route = "";
            for (int a = 0; a < components.length(); a++) {
              JSONObject component = components.getJSONObject(a);
              JSONArray types = component.getJSONArray("types");
              for (int j = 0; j < types.length(); j++) {
                String type = types.getString(j);
                if (type.equals("locality")) {
                  addr.setLocality(component.getString("long_name"));
                } else if (type.equals("street_number")) {
                  streetNumber = component.getString("long_name");
                } else if (type.equals("route")) {
                  route = component.getString("long_name");
                }
              }
            }
            addr.setAddressLine(0, route + " " + streetNumber);

            addr.setLatitude(
                result.getJSONObject("geometry").getJSONObject("location").getDouble("lat"));
            addr.setLongitude(
                result.getJSONObject("geometry").getJSONObject("location").getDouble("lng"));
            retList.add(addr);
          }
        }
      }
    } catch (IOException e) {
      Log.e(TAG, "Error calling Google geocode webservice.", e);
    } catch (JSONException e) {
      Log.e(TAG, "Error parsing Google geocode webservice response.", e);
    }

    return retList;
  }
}

请注意 Android Geocoder API中未发生的每日配额。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM