android - 服务在 geoCoder 中不可用

标签 android gps

我能够获取经度和纬度,但获取地址时出现错误。

public boolean onTouchEvent(MotionEvent 事件, MapView mapView)

{

  if(event.getAction()==0)

   {

GeoPoint p = mapView.getProjection().fromPixels(

  (int) event.getX(),

  (int) event.getY());


Geocoder geoCoder=new Geocoder(getBaseContext(),Locale.getDefault());

 try

   {

   List<Address> address = geoCoder.getFromLocation( p.getLatitudeE6() / 1E6,
                            p.getLongitudeE6() / 1E6, 1);

    String add="";

       if(address.size()>0)

          {

              for (int i=0; i<address.get(0).getMaxAddressLineIndex();i++)

        add += address.get(0).getAddressLine(i) + "\n";

          }

    Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();

            } catch (IOException e) 

            {   

                e.printStackTrace();

            }

            return true;    

        }

        return false;

我的 Logcat -->

02-14 12:27:35.717: WARN/System.err(452): java.io.IOException: Service not Available
02-14 12:27:35.727: WARN/System.err(452):     at android.location.Geocoder.getFromLocation(Geocoder.java:117)
02-14 12:27:35.727: WARN/System.err(452):     at com.parkhya.SecondGps.MainActivity$MapOverlay.onTouchEvent(MainActivity.java:47)
02-14 12:27:35.745: WARN/System.err(452):     at com.google.android.maps.OverlayBundle.onTouchEvent(OverlayBundle.java:63)
02-14 12:27:35.745: WARN/System.err(452):     at com.google.android.maps.MapView.onTouchEvent(MapView.java:643)
02-14 12:27:35.757: WARN/System.err(452):     at android.view.View.dispatchTouchEvent(View.java:3766)
02-14 12:27:35.757: WARN/System.err(452):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
02-14 12:27:35.757: WARN/System.err(452):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
02-14 12:27:35.767: WARN/System.err(452):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
02-14 12:27:35.767: WARN/System.err(452):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
02-14 12:27:35.777: WARN/System.err(452):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:863)
02-14 12:27:35.777: WARN/System.err(452):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
02-14 12:27:35.777: WARN/System.err(452):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
02-14 12:27:35.777: WARN/System.err(452):     at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
02-14 12:27:35.786: WARN/System.err(452):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
02-14 12:27:35.786: WARN/System.err(452):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
02-14 12:27:35.796: WARN/System.err(452):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-14 12:27:35.796: WARN/System.err(452):     at android.os.Looper.loop(Looper.java:123)
02-14 12:27:35.796: WARN/System.err(452):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-14 12:27:35.806: WARN/System.err(452):     at java.lang.reflect.Method.invokeNative(Native Method)
02-14 12:27:35.816: WARN/System.err(452):     at java.lang.reflect.Method.invoke(Method.java:521)
02-14 12:27:35.816: WARN/System.err(452):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-14 12:27:35.825: WARN/System.err(452):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-14 12:27:35.837: WARN/System.err(452):     at dalvik.system.NativeStart.main(Native Method)

最佳答案

这是我在 Geocoder 失败时获取地址的方法...但首先让我解释一下我自己使用 Geocoder 的经历:

由于某些未知原因,Geocoder 工作正常,突然中断!

我观察到,一段时间后(可能是几天),Geocoder 开始抛出“服务不可用”异常。

编辑->如Christian所述,即使 isPresent() 返回 true 也会抛出异常。<-EDIT END

真的很奇怪,因为它之前工作正常并且没有发生配置更改:

  • 同一台设备
  • 相同的 Android 版本
  • 相同的应用
  • 相同的 list
  • WIFI 已启动并正在运行,设置中已启用设备定位功能

当然,某些发生了变化,但目前我们还不知 Prop 体是什么。 有一个关于此的错误:Issue 38009: 4.1.1 Geocoder throwing exception: IOException: Service not Available

此线程 (ATTOW) 上的最后一篇文章“可能它会在 android 4.0.x + 目标 API x 中定期重现”

作为解决方法,您可以使用Google map

这是我的 GeocoderHelper 类,它提供了一个“谷歌地图”B 计划,以防 Geocoder 开始失败。 就我而言,我只对 CityName 感兴趣,但您基本上可以在 google map JSON 输出中获取任何可用数据

用法:

new GeocoderHelper().fetchCityName(context, location); Then do somthing in onPostExecute() of example code (send broadcast, invoke listener method, set a textView text, whatever)

GeocoderHelper 类:

package com.<your_package>.location;

import java.util.List;
import java.util.Locale;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.util.Log;

public class GeocoderHelper
{
    private static final AndroidHttpClient ANDROID_HTTP_CLIENT = AndroidHttpClient.newInstance(GeocoderHelper.class.getName());

    private boolean running = false;

    public void fetchCityName(final Context contex, final Location location)
    {
        if (running)
            return;

        new AsyncTask<Void, Void, String>()
        {
            protected void onPreExecute()
            {
                running = true;
            };

            @Override
            protected String doInBackground(Void... params)
            {
                String cityName = null;

                if (Geocoder.isPresent())
                {
                    try
                    {
                        Geocoder geocoder = new Geocoder(contex, Locale.getDefault());
                        List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
                        if (addresses.size() > 0)
                        {
                            cityName = addresses.get(0).getLocality();
                        }
                    }
                    catch (Exception ignored)
                    {
                        // after a while, Geocoder start to trhow "Service not availalbe" exception. really weird since it was working before (same device, same Android version etc..
                    }
                }

                if (cityName != null) // i.e., Geocoder succeed
                {
                    return cityName;
                }
                else // i.e., Geocoder failed
                {
                    return fetchCityNameUsingGoogleMap();
                }
            }

            // Geocoder failed :-(
            // Our B Plan : Google Map
            private String fetchCityNameUsingGoogleMap()
            {
                String googleMapUrl = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + location.getLatitude() + ","
                        + location.getLongitude() + "&sensor=false&language=fr";

                try
                {
                    JSONObject googleMapResponse = new JSONObject(ANDROID_HTTP_CLIENT.execute(new HttpGet(googleMapUrl),
                            new BasicResponseHandler()));

                    // many nested loops.. not great -> use expression instead
                    // loop among all results
                    JSONArray results = (JSONArray) googleMapResponse.get("results");
                    for (int i = 0; i < results.length(); i++)
                    {
                        // loop among all addresses within this result
                        JSONObject result = results.getJSONObject(i);
                        if (result.has("address_components"))
                        {
                            JSONArray addressComponents = result.getJSONArray("address_components");
                            // loop among all address component to find a 'locality' or 'sublocality'
                            for (int j = 0; j < addressComponents.length(); j++)
                            {
                                JSONObject addressComponent = addressComponents.getJSONObject(j);
                                if (result.has("types"))
                                {
                                    JSONArray types = addressComponent.getJSONArray("types");

                                    // search for locality and sublocality
                                    String cityName = null;

                                    for (int k = 0; k < types.length(); k++)
                                    {
                                        if ("locality".equals(types.getString(k)) && cityName == null)
                                        {
                                            if (addressComponent.has("long_name"))
                                            {
                                                cityName = addressComponent.getString("long_name");
                                            }
                                            else if (addressComponent.has("short_name"))
                                            {
                                                cityName = addressComponent.getString("short_name");
                                            }
                                        }
                                        if ("sublocality".equals(types.getString(k)))
                                        {
                                            if (addressComponent.has("long_name"))
                                            {
                                                cityName = addressComponent.getString("long_name");
                                            }
                                            else if (addressComponent.has("short_name"))
                                            {
                                                cityName = addressComponent.getString("short_name");
                                            }
                                        }
                                    }
                                    if (cityName != null)
                                    {
                                        return cityName;
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ignored)
                {
                    ignored.printStackTrace();
                }
                return null;
            }

            protected void onPostExecute(String cityName)
            {
                running = false;
                if (cityName != null)
                {
                    // Do something with cityName
                    Log.i("GeocoderHelper", cityName);
                }
            };
        }.execute();
    }
}

希望这会有所帮助。

关于android - 服务在 geoCoder 中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9272918/

相关文章:

android - Gradle 无法通过 Nexus 解决依赖关系,但会在浏览器中下载 Artifact

android - 使 HttpLoggingInterceptor 不记录图像

android等待线程的 Activity

android - 使用 Google Play Location API 获得速度

android - 如果使用网络位置提供程序(相对于 GPS),电池功耗是否有优势?

android - 如何知道卫星已经在 android 上找到或正在搜索?

javascript - 如何使用phonegap在android中检测来电号码

java - 如何在Android中制作垂直选择器?

javascript - 为什么经度/纬度加权计算在 JavaScript 中给出与 SQL 不同的结果

java - 在两个 Android 应用程序之间共享数据