为啥 Android Geocoder 会抛出“服务不可用”异常?

Posted

技术标签:

【中文标题】为啥 Android Geocoder 会抛出“服务不可用”异常?【英文标题】:Why is Android Geocoder throwing a "Service not Available" exception?为什么 Android Geocoder 会抛出“服务不可用”异常? 【发布时间】:2011-06-13 06:16:13 【问题描述】:

应用程序使用Geocoder 对象。它在我的股票 Froyo Nexus One 上运行良好。但后来我在不同的设备上运行完全相同的应用程序(Advent Vega 10" 平板电脑也运行 Froyo),我得到了这个异常:服务不可用。我使用的方法是getFromLocationName() ,我正在针对 android 1.6 Google API 构建。

我知道在模拟器上引发此异常的问题,但我怀疑这是不同的。为什么会在一台运行 Froyo 的设备上而不是另一台设备上?

该应用是定位应用,由于平板没有GPS或移动网络,在Wi-Fi连接不提供位置的场景下,用户必须手动指定,因此无法使用Geocoder 对象是个坏消息。

我可以为用户添加一种在地图上选择位置的方法,但这并不理想。可能我可以直接使用 Google Maps API,但我很想先了解问题的性质,如果有一个更简单的解决方案会很好。

希望在未来的版本中,Android 将为非地理编码器设备提供操作系统级别的“默认位置”,因此位置感知应用可以在 Google TV 等设备上开箱即用。

【问题讨论】:

我在文档中看到它说“Geocoder 类需要一个未包含在核心 android 框架中的后端服务”,但为什么设备供应商不包含它?搞错了? Geocoder 后端是否被视为经 Google 批准的 Android 发行版的一部分?该平板电脑未经 Google 认证,因此默认情况下没有 Google Android 应用程序(GMail、Market 等)。我怀疑这就是原因。看起来这些类型的设备上的人可能不得不从地图上选择位置,或者我可以直接使用该 Maps API。排除它似乎很奇怪,很想知道为什么它不存在。 【参考方案1】:

我请 Google 的 Reto Meier 确认我的理论是正确的,他说“正确。Geocoder 是 Google API 插件的一部分,不是 AOSP 的一部分。” p>

因此,任何不附带 Play 商店、GMail 应用程序等的设备也将缺少 Geocoder 后端。

【讨论】:

好吧——它曾经在之前 2.2的模拟器上工作,所以它不像一直这样。 你如何看待this?它指出“Google API 插件还包括一个地理编码器后端服务实现”。这是否意味着针对 Google API 附加组件而不是仅基于基本的 Android SDK 构建您的项目会自动将后端包含到您的 .apk 中?我注意到您是针对 v1.6 的 Google API(而不是基本的 Android SDK)构建的,所以我猜答案是否定的,因为它不适合您。顺便说一句,您是如何与 Reto Meier 交谈的? 另请注意:如果您针对 API 9 或更高版本进行构建,则有一个方法 Geocoder.isPresent() 会告诉您是否在该设备上实现了 getFromLocation... 方法(我不知道如果这与存在后端相同)。此外,即使没有 GApps、Market 等,设备 可能 仍然存在后端/实现,就像 Kindle Fire 一样(Geocoder.isPresent() 在 Fire 上为我返回 true),我猜是亚马逊决定包括一个。 好吧,我之前的评论弄错了,即使Geocoder.isPresent() 在 Kindle Fire 上返回 true,尝试拨打 getFromLocationName() 仍然会引发 IOException: Service Not Available,我猜这意味着没有后端。所以它接缝isPresent() 是非常没用的。我还针对“Google Addon APIs”而不是基本的 Android SDK 构建了我的项目,它没有任何区别。这让我很想知道在我的第一个链接中“Google API 插件还包括地理编码器后端服务实现”是什么意思。 @OllieC 几周前我已经成功实现了getFromLocationName(),这在模拟器和设备上都运行良好...??但现在getFromLocation() 正在抛出服务不可用 异常...【参考方案2】:

似乎有another possible workaround for this problem,不幸的是,它被标记为重复问题,因此可能会被遗漏。从本质上讲,重新启动设备可以解决问题。请注意,我将其称为“解决方法”而不是“解决方案”。 :(

【讨论】:

我正在寻找一种替代方法来解决此错误,而无需重新启动设备。它存在吗? 我找到了!为避免重新启动,您需要将项目构建目标设置为 API 16。在 Eclipse 中:右键单击项目 -> 构建路径 -> 配置构建路径 -> Android -> 项目构建目标。 将 Target API 更改为 16 真的解决了问题吗?别人试过吗?因为在另一条评论(***.com/a/15340668/778891)中,作者说它毕竟不起作用。 这对我有用。我在 4.1 上遇到了同样的问题,显然 确实 安装了 Google Play 和所有的东西。【参考方案3】:

对于那些寻找替代方案的人,希望我在另一篇文章中的回答是有用的。 在地理编码中发现错误时,您可以使用Google Geocoding API。

更多代码 => Get current location using json

【讨论】:

【参考方案4】:

有些设备不支持地理编码器,所以您需要做的是创建自己的地理编码器。

基本上你需要创建一个异步任务来向 google 请求地址并处理 json 响应。

使用查询,我做这样的事情:

public void asyncJson(String address)
        address = address.replace(" ", "+");

        String url = "http://maps.googleapis.com/maps/api/geocode/json?address="+ address +"&sensor=true";

        aq.ajax(url, JSONObject.class, new AjaxCallback<JSONObject>() 

                @Override
                public void callback(String url, JSONObject json, AjaxStatus status)                         

                        if(json != null)

                                 //here you work with the response json
                                 JSONArray results = json.getJSONArray("results");                               
                                Toast.makeText(context, results.getJSONObject(1).getString("formatted_address"));

                        else                                
                                //ajax error, show error code
                                Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
                        
                
        );        

【讨论】:

【参考方案5】:

浪费了几个小时后,我得到了一个最简单的解决方案。

我刚刚重启了我的设备,它开始工作了。

看来,问题是由于某些操作系统级别的缓存问题造成的。希望它也对你有用..

【讨论】:

【参考方案6】:

我有同样的问题。我使用了以下函数。

注意:

在你的Activity中使用context,不要在下面的函数中使用getApplicationContext()

public static Address getLocalityFrmGeoCoder(Context context, Location mLocation) 
        try 
            if(mLocation!=null)
            Geocoder gCoder = new Geocoder(context, Locale.getDefault());
            List<Address> address = gCoder.getFromLocation(mLocation.getLatitude(), mLocation.getLongitude(), 1);
            if (address.size() > 0) 
                return address.get(0);
            
            

         catch (Exception e) 
            Log.d("GEOCODER", "GEOCODER EXCEPTION");
            e.printStackTrace();

        
    return null;

【讨论】:

以上是关于为啥 Android Geocoder 会抛出“服务不可用”异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 npm start 会抛出 events.js:187 throw er; // 我的反应项目中未处理的“错误”事件?

为啥有时会抛出 FileNotFoundException

为啥“prepareCall”会抛出 NumberFormatException?

为啥 BluetoothSetLocalServiceInfo 会抛出错误 1314?

为啥geoip会抛出异常?

为啥这个 OdbcConnection 会抛出 System.InvalidOperationException?