Android Geocoder在某些设备上的行为有所不同 [英] Android Geocoder behaves different on some devices

查看:149
本文介绍了Android Geocoder在某些设备上的行为有所不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码,它在某些设备上可以完美运行,而在其他设备上则可以正常运行 getFromLocationName 返回大小为0的列表.

I have the below code, it works perfectly on some devices and in others the function getFromLocationName return a list with size 0.

例如,在Nexus 6p中它返回正确的结果 并在Meizu MX5中返回大小为0的列表.

For example, in Nexus 6p it returns the correct result and in Meizu MX5 it returns a list with size 0.

我具有相同的权限,并且两个设备都启用了GPS. Nexus 6p上的Android版本是7.1.2,而Meizu MX5上的Android版本是5.1

I have the same permissions and GPS enable for both devices. Android version on the Nexus 6p is 7.1.2 and on Meizu MX5 is 5.1

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

注释:

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

那为什么会有区别呢?它与设备上的Android版本有关吗?

So why the difference? Is it related to the Android version on the devices?

推荐答案

Android中的Geocoder实际上并非在所有设备上都具有相同的行为.我已经使用以下设备测试了Geocoder:

Geocoder in Android is really don't have the same behaviour on all devices. I have tested the Geocoder with the following devices:

  • 三星(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时.

All the devices returning the list but Xiaomi, it returns zero lists. So, we can't depend on Geocoder. The solution is to create our own Geocoder implementation using Google Geocoding API and use it whenever the list returns 0.

这里是Geocoder的实现(我是从SO那里找到的,但记不清了),可以像使用Geocoder一样有效地使用:

Here the implementation of Geocoder (I found it from SO, but can't remember the source) which can be used exatly like using the 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中没有发生的每日配额.

Be aware of the daily quota which didn't happen in Android Geocoder API.

这篇关于Android Geocoder在某些设备上的行为有所不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆