【问题标题】:geocoder.getFromLocation function throws "Timed out waiting for server response" exceptiongeocoder.getFromLocation 函数抛出“等待服务器响应超时”异常
【发布时间】:2014-05-13 17:37:50
【问题描述】:

我试图通过从 MainActivity 启动 IntentService 来获取用户的位置。在服务内部,我尝试对 try 块内的位置进行反向地理编码,但是当我捕获异常并打印时,它显示“等待服务器响应超时”异常。但有几次我得到了位置。所以我认为什么都没有我的代码有问题。但是如果它在 10 次中抛出 8 次异常,它就没有用了。所以你能建议一些避免这种情况的方法吗?

【问题讨论】:

  • Android 上的 GeoCoder 存在大量问题,您将遇到的下一个问题将是 code.google.com/p/android/issues/detail?id=38009,该服务会自行终止,唯一的解决方案是重新启动设备,这是一个完全不可接受的解决方案...您最好将请求直接发送到谷歌的地理编码器网站并解析数据developers.google.com/maps/documentation/geocoding 但是,请注意,数据并不总是一致的,不同的国家定义不同的属性
  • 是不是因为我们可以向服务器发送多少请求有一些限制?
  • 我确信它有某种限制,但我怀疑这是您的问题(除非您发送垃圾邮件或其他什么)。但同样,即使你没有这样做,你仍然会毫无疑问地遇到我上面提到的问题,所以我建议实施一个替代方案。
  • 这里是一个替代示例:stackoverflow.com/questions/19059894/…

标签: android performance


【解决方案1】:

http://maps.googleapis.com/maps/api/geocode/json?latlng=lat,lng&sensor=true

Geocoder 存在等待服务器响应超时的错误。或者,您可以从代码中点击此请求以获取相应 lat,lng 位置地址的 json 响应。

【讨论】:

    【解决方案2】:

    由于互联网连接不可用,我遇到了错误。

    请检查是否已分配互联网权限:

     <uses-permission android:name="android.permission.INTERNET" />
    

    并仔细检查您的互联网是否开启。

    为了获得响应,我在 AsyncTask 中编写代码,如下所示:

     class GeocodeAsyncTask extends AsyncTask<Void, Void, Address> {
    
            String errorMessage = "";
    
            @Override
            protected void onPreExecute() {
    
                progressBar.setVisibility(View.VISIBLE);
            }
    
            @Override
            protected Address doInBackground(Void ... none) {
                Geocoder geocoder = new Geocoder(DashboardActivity.this, Locale.getDefault());
                List<Address> addresses = null;
    
    
                double latitude = Double.parseDouble(strLatitude);
                double longitude = Double.parseDouble(strLongitude);
    
                try {
                    addresses = geocoder.getFromLocation(latitude, longitude, 1);
                } catch (IOException ioException) {
                    errorMessage = "Service Not Available";
                    Log.e(TAG, errorMessage, ioException);
                } catch (IllegalArgumentException illegalArgumentException) {
                    errorMessage = "Invalid Latitude or Longitude Used";
                    Log.e(TAG, errorMessage + ". " +
                            "Latitude = " + latitude + ", Longitude = " +
                            longitude, illegalArgumentException);
                }
    
    
                if(addresses != null && addresses.size() > 0)
                    return addresses.get(0);
    
                return null;
            }
    
            protected void onPostExecute(Address address) {
                if(address == null) {
                    progressBar.setVisibility(View.INVISIBLE);
    
                    tvcurrentLOc.setText(errorMessage);
                }
                else {
                    String addressName = "";
                    for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                        addressName += "," + address.getAddressLine(i);
                    }
                    progressBar.setVisibility(View.INVISIBLE);
    
                    tvcurrentLOc.setText(addressName);
                }
            }
        }
    

    希望它会有所帮助。

    【讨论】:

      【解决方案3】:

      这是解决此问题的快速解决方案。

      public class GPSL extends Service implements LocationListener {
      public Location getLocation() {
              try {
                  locationManager = (LocationManager) mContext
                          .getSystemService(LOCATION_SERVICE);
      
                  // getting GPS status
                  isGPSEnabled = locationManager
                          .isProviderEnabled(LocationManager.GPS_PROVIDER);
      
                  // getting network status
                  isNetworkEnabled = locationManager
                          .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
      
                  if (!isGPSEnabled && !isNetworkEnabled) {
                      // no network provider is enabled
                  } else {
                      this.canGetLocation = true;
                      // First get location from Network Provider
                      if (isNetworkEnabled) {
                          try
                          {
                              locationManager.requestLocationUpdates(
                                      LocationManager.NETWORK_PROVIDER,
                                      MIN_TIME_BW_UPDATES,
                                      MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                              Log.d("Network", "Network");
                              if (locationManager != null) {
                                  location = locationManager
                                          .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                                  if (location != null) {
                                      latitude = location.getLatitude();
                                      longitude = location.getLongitude();
                                  }
                              }
                          }
                          catch (SecurityException e)
                          {
                              e.printStackTrace();
                          }
      
                      }
                      // if GPS Enabled get lat/long using GPS Services
                      if (isGPSEnabled) {
                          if (location == null) {
                              try
                              {
                                  locationManager.requestLocationUpdates(
                                          LocationManager.GPS_PROVIDER,
                                          MIN_TIME_BW_UPDATES,
                                          MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                                  Log.d("GPS Enabled", "GPS Enabled");
                                  if (locationManager != null) {
                                      location = locationManager
                                              .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                      if (location != null) {
                                          latitude = location.getLatitude();
                                          longitude = location.getLongitude();
                                      }
                                  }
                              }
                              catch (SecurityException e)
                              {
                                  e.printStackTrace();
                              }
      
                          }
                      }
                  }
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
              return location;
          }
      
      public List<Address> getGeocoderAddress(Context context) {
              if (location != null) {
      
                  Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
      
                  try {
                      /**
                       * Geocoder.getFromLocation - Returns an array of Addresses
                       * that are known to describe the area immediately surrounding the given latitude and longitude.
                       */
                      List<Address> addresses = geocoder.getFromLocation(latitude, longitude, this.geocoderMaxResults);
      
                      return addresses;
                  } catch (IOException e) {
                      //e.printStackTrace();
                      Log.e("Gecoder", "Impossible to connect to Geocoder", e);
                  }
              }
      
              return null;
          }
      
          /**
           * Try to get AddressLine
           * @return null or addressLine
           */
          public String getAddressLine(Context context) {
              List<Address> addresses = getGeocoderAddress(context);
      
              if (addresses != null && addresses.size() > 0) {
                  Address address = addresses.get(0);
                  String addressLine = address.getAddressLine(0);
      
                  return addressLine;
              } else {
                  return null;
              }
          }
      
          /**
           * Try to get Locality
           * @return null or locality
           */
          public String getLocality(Context context) {
              List<Address> addresses = getGeocoderAddress(context);
      
              if (addresses != null && addresses.size() > 0) {
                  Address address = addresses.get(0);
                  String locality = address.getLocality();
      
                  return locality;
              }
              else {
                  return null;
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        这是一个简单而有效的解决方案:

        创建以下两个函数:

        public static JSONObject getLocationInfo(String address) {
            StringBuilder stringBuilder = new StringBuilder();
            try {
        
            address = address.replaceAll(" ","%20");    
        
            HttpPost httppost = new HttpPost("http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false");
            HttpClient client = new DefaultHttpClient();
            HttpResponse response;
            stringBuilder = new StringBuilder();
        
        
                response = client.execute(httppost);
                HttpEntity entity = response.getEntity();
                InputStream stream = entity.getContent();
                int b;
                while ((b = stream.read()) != -1) {
                    stringBuilder.append((char) b);
                }
            } catch (ClientProtocolException e) {
            } catch (IOException e) {
            }
        
            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject = new JSONObject(stringBuilder.toString());
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        
            return jsonObject;
        }
        private static List<Address> getAddrByWeb(JSONObject jsonObject){
            List<Address> res = new ArrayList<Address>();
            try
            {
                JSONArray array = (JSONArray) jsonObject.get("results");
                for (int i = 0; i < array.length(); i++)
                {
                    Double lon = new Double(0);
                    Double lat = new Double(0);
                    String name = "";
                    try
                    {
                        lon = array.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
        
                        lat = array.getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
                        name = array.getJSONObject(i).getString("formatted_address");
                        Address addr = new Address(Locale.getDefault());
                        addr.setLatitude(lat);
                        addr.setLongitude(lon);
                        addr.setAddressLine(0, name != null ? name : "");
                        res.add(addr);
                    }
                    catch (JSONException e)
                    {
                        e.printStackTrace();
        
                    }
                }
            }
            catch (JSONException e)
            {
                e.printStackTrace();
        
            }
        
            return res;
        }
        

        现在只需替换​​

        geocoder.getFromLocation(locationAddress, 1); 
        

        与

        getAddrByWeb(getLocationInfo(locationAddress));  
        

        【讨论】:

        • 直接通过 HTTP 而不是 SDK 调用 API 可能会导致 Google API 费用显着增加。当然,除非 API 对您的 puprose 是免费的,但通常不是。但是 SDK 是免费的。
        • 那么使用Geocoder android api 比调用http api 好还是不好?
        • 此答案从地址获取位置,而不是纬度/经度,这就是 getFromLocation 所做的。
        • 该答案不返回 getLocality()。但是如何返回 getAddressLine(0)
        猜你喜欢
        • 2016-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-23
        • 2011-10-04
        相关资源
        最近更新 更多