geoCoder 中不提供服务

发布于 2025-01-05 02:43:39 字数 3716 浏览 0 评论 0原文

我可以获得经度和纬度,但获取地址时出现错误。

public boolean onTouchEvent(MotionEvent event, 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)

I am able to get longitude and latitude but getting address i got an error.

public boolean onTouchEvent(MotionEvent event, 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;

}

My 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心舞飞扬 2025-01-12 02:43:39

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

出于某种未知的原因,Geocoder 工作正常,然后突然中断!

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

编辑->正如 Christian 提到的,即使 isPresent() 返回 true,也会引发异常。<-编辑END< /strong>

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

  • 相同的设备
  • 相同的 Android 版本
  • 相同的应用程序
  • 相同的清单
  • WIFI 启动并运行,在设置中启用了设备位置功能

当然,有些东西发生了变化,但是,对于目前,我们还不知道到底是什么。
有一个关于此问题的错误:Issue 38009: 4.1.1 Geocoder throwing exception :IOException:服务不可用

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

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

这是我的GeocoderHelper类,它提供了“Google Map”B Plan,以防Geocoder启动失败。
就我而言,我只对 CityName 感兴趣,但您基本上可以在 google 地图 JSON 输出中获取任何可用数据

用法:

new GeocoderHelper().fetchCityName(context, location);
然后在示例代码的 onPostExecute() 中执行一些操作(发送广播、调用侦听器方法、设置 textView 文本等)

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();
    }
}

希望这会有所帮助。

Here is my way to get the address even if Geocoder failed... but first let me explain my own experience with Geocoder:

For some unknown reason, Geocoder works fine then, suddenly break!.

What I observed is that, after a while (can be days), Geocoder start to throw "Service not available" exception.

EDIT-> As mentioned by Christian, the exception is thrown even is isPresent() returns true.<-EDIT END

Really weird since it was working fine before and no configuration changed occurred:

  • same device
  • same Android version
  • same app
  • same manifest
  • WIFI up and running, Device location feature enabled in settings

Of course, something changed, but, for the time being, we don't know exactly what.
There is a bug opened about that: Issue 38009: 4.1.1 Geocoder throwing exception: IOException: Service not Available

Last post on this thread (ATTOW) "Probably it's periodically reproducible in android 4.0.x + target API x"

As a workaround, you can use Google Map

Here is my GeocoderHelper class that provides a 'Google Map' B Plan in case Geocoder start to fails.
In my case, I am just interested in CityName, but you can basically get any data availalbe in google map JSON output

Usage:

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

GeocoderHelper Class:

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();
    }
}

Hope this will help.

请别遗忘我 2025-01-12 02:43:39

GeoCoder 服务可能会也可能不会被实现,因为它不是核心 Android 框架的一部分。 此处查看 GeoCoder 的文档

您需要使用 google API 并解析json 响应中的地址,使其适用于所有设备。

用于处理地理编码和反向地理编码的类。地理编码是将街道地址或其他位置描述转换为(纬度、经度)坐标的过程。反向地理编码是将(纬度、经度)坐标转换为(部分)地址的过程。反向地理编码位置描述中的详细信息量可能会有所不同,例如,一个可能包含最近建筑物的完整街道地址,而另一个可能仅包含城市名称和邮政编码。 Geocoder 类需要一个未包含在核心 Android 框架中的后端服务。如果平台中没有后端服务,Geocoder 查询方法将返回空列表。使用 isPresent() 方法确定 Geocoder 实现是否存在。

GeoCoder service may/maynot be implemented as it is not part of core android framework. Check the documentation for GeoCoder here

You need to use google APIs and parse the address from the json response for it to work on all the devices.

A class for handling geocoding and reverse geocoding. Geocoding is the process of transforming a street address or other description of a location into a (latitude, longitude) coordinate. Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a (partial) address. The amount of detail in a reverse geocoded location description may vary, for example one might contain the full street address of the closest building, while another might contain only a city name and postal code. The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform. Use the isPresent() method to determine whether a Geocoder implementation exists.

变身佩奇 2025-01-12 02:43:39

问题是 NetworkLocationService 可能不再运行。

只能通过重新启动来解决。 (NetworkLocationService 在启动时加载)

The problem is that NetworkLocationService may be no longer running.

It can be only solved by a reboot. (The NetworkLocationService is loaded at boot)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文