繁体   English   中英

java.io.IOException:grpc 失败

[英]java.io.IOException: grpc failed

当我使用 call getFromLocationName 时,我得到一个描述为“grpc failed”的 IOException。

运行的代码

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    try {
        Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
        List<Address> listAdresses = geocoder.getFromLocationName("London", 10);
        Log.i("PlaceInfo", listAdresses.get(0).toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

控制台输出错误:

07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err: java.io.IOException: grpc failed
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.location.Geocoder.getFromLocationName(Geocoder.java:178)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at co.siqve.maplocationdemo.MapsActivity.onMapReady(MapsActivity.java:70)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.zzaj.zza(Unknown Source)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.internal.zzaq.onTransact(Unknown Source)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Binder.transact(Binder.java:499)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.internal.aq.a(:com.google.android.gms.DynamiteModulesB:5)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.maps.api.android.lib6.impl.bb.run(:com.google.android.gms.DynamiteModulesB:5)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Looper.loop(Looper.java:154)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Android SDK 版本(API 级别):25

Android Studio 插件是最新的。

提前致谢!

编辑:

现在问题似乎已解决,这是我的解决方案。

可能您仅在 genymotion 和 android studio 模拟器中遇到此问题。 我在使用 genymotion 和 android studio 模拟器时遇到了同样的问题,然后我在 android 真实设备中检查了它。 它对我很有用。 你在真机上检查过吗?

就像谷歌写的,你不应该在 UI 线程上调用这个方法

https://developer.android.com/training/location/display-address#java

我通过在新Thread运行此操作来解决此问题,然后如果我需要更新某些 UI 视图,我将在runOnUiThread

当我的真实设备上没有互联网连接时,我可以重现这个问题(java.io.IOException: grpc failed)。

我在 Android 4.4.2 设备上多次遇到这个问题。 对我来说,解决方案只是重新启动手机。 没有代码更新没有Android studio卸载。

这个问题出现在我身上(即使我在后台线程上发出请求),但仅在 Android Studio 模拟器中出现。 为我修复它的一个奇怪的解决方法是打开然后关闭飞行模式!

这也发生在我安装了奥利奥的三星 S7 Edge 手机上。 它只发生在我打开飞行模式时(并不总是 - 意味着某些东西可能已被缓存)。 我没有探索 Geocoder 的本质,但我认为它需要某种连接来获取信息(这也可以解释为什么在模拟器上经常发生这种情况)。 对我来说,解决方案是检查网络连接状态并仅在status != NETWORK_STATUS_NOT_CONNECTED时调用它。

为此,您可以实现一个广播接收器,它将侦听网络上的任何状态变化。

注册接收者

IntentFilter networkFilter = new IntentFilter();
networkFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
getActivity().registerReceiver(NetworkChangeReceiver, networkFilter);

设置广播接收器来处理广播

private BroadcastReceiver NetworkChangeReceiver = new BroadcastReceiver() {

  @Override
  public void onReceive(final Context context, final Intent intent) {
    int status = NetworkUtil.getConnectivityStatusString(context);

    if (status == NetworkUtil.NETWORK_STATUS_NOT_CONNECTED) {
    } else {
      // do your stuff with geocoder here
    }
  }
};

截至 2019 年 8 月,当我使用代理窥探自己的 http 流量时,我仍然不时收到此信息。 关闭它,问题就消失了。

今天 (2017-09-16) 我的 Android Studio (2.3.3) 将Google Play 服务更新到了修订版 44 问题后来得到了解决。 我这边没有任何代码或设置更改。

虽然这个问题很晚,但这里是Kotlin用户的答案。

我在使用 Geocoder 的getFromLocation函数时偶然发现了这个java.io.IOException: grpc failed错误。 我一直使用 Google Pixel 2 作为我的测试设备(运行 Android 9)。

有3件事需要确保:

  1. 正如许多在这里(和Android文档中提到这里),与任何Geocoder需要从你的应用程序的主线程分开进行。 为了支持我的说法,这里引用了 Android 文档中的一段话: “该方法是同步的,可能需要很长时间才能完成其工作,因此您不应从应用程序的主用户界面 (UI) 线程调用它。 ”

现在,最好使用IntentService来完成这个任务,就像官方文档给出的例子一样。 但是, 此人使用 Java 中的 AsyncTask 进行了尝试,并且效果很好(请注意,他们使用geocoder的任务强度要低得多)。 因此,我强烈建议使用doAsyncdoAsync方法并在其中实现有关Geocoder任何代码。

  1. 如果可能,请使用物理设备而不是模拟器。 Android Studio 上的模拟器给我带来了很多麻烦,并且没有给我真正调试问题所需的错误信息。

  2. 在您的物理设备上重新安装您的应用程序并多次使缓存无效/重新启动您的项目。

还要确保您有良好的网络连接,并且在您的设备上已启用。

我在使用 geocoder.getFromLocation() 方法获取地址列表时遇到了这个问题,问题是从纬度、经度获取地址列表需要时间,或者在某些慢速设备上需要更多时间,有时它还会给我 java-io- ioexception-grpc 失败。

我使用 Rx Java 解决了这个问题。

public class AsyncGeocoder {

private final Geocoder geocoder;

public AsyncGeocoder(Context context) {
    geocoder = new Geocoder(context);
}

public Disposable reverseGeocode(double lat, double lng, Callback callback) {
    return Observable.fromCallable(() -> {
        try {
            return geocoder.getFromLocation(lat, lng, 1);
        } catch (Exception e) {
            AppLogger.d("throwable,", new Gson().toJson(e));
            e.printStackTrace();
        }
        return false;
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(result -> {
                //Use result for something
                AppLogger.d("throwable,", new Gson().toJson(result));

                callback.success((Address) ((ArrayList) result).get(0));
            }, throwable -> AppLogger.d("throwable,", new Gson().toJson(throwable)));
}

public interface Callback {
    void success(Address address);

    void failure(Throwable e);
}
}

呼叫位置

mViewModel.getLocation(asyncGeocoder, getLat(), getLng(), this);

视图模型方法

public void getLocation(AsyncGeocoder geocoder, Double lat, Double lng, AsyncGeocoder.Callback callback) {
        getCompositeDisposable().add(geocoder.reverseGeocode(lat, lng, callback));
    }

有时,当经纬度包含 3 个小数位以上时,Geocoder 会失败,或者说 Geocoder 无法解码每个经纬度。 您需要将纬度和经度限制为最多 3 个小数位。 完整代码

        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(3);

        double lat = Double.parseDouble(df.format(currentUserLocation.latitude));
        double lon = 
        Double.parseDouble(df.format(currentUserLocation.longitude));
        Geocoder geocoder = new Geocoder(myContext, Locale.getDefault());

        List<Address> addresses  = geocoder.getFromLocation(lat,lon, 1);

        String cityName = addresses.get(0).getLocality();

我最终通过对 25 版 SDK、构建工具和 API 模拟器使用以下配置来使其工作。

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example..."
        minSdkVersion 15
        targetSdkVersion 25

还使用 Google API 版本 11.0.2。

我认为这取决于设备的位置。 因为谷歌地图有时在某些地区无法正常工作。 我来自伊朗,我在真实设备和模拟器上也遇到了这个问题。 过了一段时间解决了这个问题,我使用了一个 vpn 应用程序,它可以在真实设备和模拟器上运行。 因为 vpn 应用程序更改了我的 IP 地址。

哎呀! 设备 Gps的精度模式改为(仅 gps)其他选项的即时,然后尝试......

为我工作的设置是这样的,我是邮递员,你也可以在模拟器上找到它们

这个问题已经被报告了,你可以找到其他讨论它的堆栈帖子。 是对 google 问题的评论,其中包含一些地理编码器崩溃的不同方式。 我建议你用 try 和 catch 包围你的代码部分,这样你的应用程序就不会停止。

在 Wifi 连接中工作正常,但在 3g 或 4g 连接中失败。

使用代理

根据我的经验,我可以说这个错误是由GeocodergetFromLocation()方法引发的。 所以不要做以下事情:

  • 不要在主线程上调用这个方法。 这将冻结 UI,如果任何取决于此方法结果的内容都会崩溃。 处理这个案子。
  • 当没有互联网连接时,将再次抛出IOExeption 同样,任何取决于此方法结果的内容都会崩溃。 处理这个案子。

经过一些研究弄清楚如何解决这个问题,在我的情况下,像将代码放入新Thread或使用GeocodingApi类的所有方法都不起作用,我只是确保

play-services-base

play-services-location

有如下相同的版本:

implementation 'com.google.android.gms:play-services-base:17.1.0'

implementation 'com.google.android.gms:play-services-location:17.1.0'

就我而言,我刚刚从应用程序权限设置中打开(授予权限)位置。

如果将 Geocoder 作为应用程序的单例引入而不是每次都创建它,它对我有用。 确保从工作线程调用 Geocoder.getFromLocationName()。

例如:

class Application {
    private val geoCoder = Geocoder(context, Locale.getDefault())
    ...
}

class SomeClass {

    @WorkerThread
    fun doSmth(){
       application.geoCoder.getFromLocationName("London", 10)
       ...
    }
}

我遇到了同样的问题,不知道问题出在哪里。 完全......直到最近,当我配置了代理时,我开始注意到这个问题出现在真实设备上。 当我在 MAC 上使用 charles 时没有问题,但是当我开始在 Linux 上使用 MITM 时,这个问题每次都开始出现,无一例外。 可能需要额外配置MITM。 但最重要的是,如果你关闭你的代理,你应该没问题。

所以看看吧。

当我使用getFromLocationName调用时,我得到一个IOException,描述为“ grpc failed”。

运行的代码

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    try {
        Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
        List<Address> listAdresses = geocoder.getFromLocationName("London", 10);
        Log.i("PlaceInfo", listAdresses.get(0).toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

错误的控制台输出:

07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err: java.io.IOException: grpc failed
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.location.Geocoder.getFromLocationName(Geocoder.java:178)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at co.siqve.maplocationdemo.MapsActivity.onMapReady(MapsActivity.java:70)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.zzaj.zza(Unknown Source)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.internal.zzaq.onTransact(Unknown Source)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Binder.transact(Binder.java:499)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.android.gms.maps.internal.aq.a(:com.google.android.gms.DynamiteModulesB:5)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.google.maps.api.android.lib6.impl.bb.run(:com.google.android.gms.DynamiteModulesB:5)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.os.Looper.loop(Looper.java:154)
07-10 12:01:38.781 13712-13712/co.siqve.maplocationdemo W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
07-10 12:01:38.782 13712-13712/co.siqve.maplocationdemo W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Android SDK版本(API级别):25

Android Studio插件是最新的。

提前致谢!

编辑:

现在问题似乎已经解决,这是我的解决方案。

我似乎通过打开手机的顶部工具栏并在 wifi 和网络之间切换来解决此问题,我猜所有虚拟设备上的操作内存都设置为 2GB RAM 并且查找位置使用太多因此,我看到了跳过帧和位置无法搜索。 因此,如果它消除了这个错误,只需从 Wifi 切换到网络,然后向后切换。

就我而言,我删除了 AVD 并重新安装,一切正常。

嗨,我在返回旧项目/测试手机后遇到“grpc 失败”错误。

我的代码正在调用 getFromLocation() 方法并且失败了。 阅读和玩了几个小时,我想我会检查谷歌地图是否有效,它在空白地图上显示了我的位置,wifi 已关闭,所以我打开了 WIFI,地图工作正常。

重新测试的应用程序,瞧,我的 getFromLocation() 方法正在运行,所以在定位服务区域中一定有一些粘滞的东西......

List<Address> addresses  = geocoder.getFromLocation(lat,lon, 1);

地址的大小通常为 0。这可能是由于未能达到峰值地址,因此将它们标记为“未知”或“默认”可能是一个选项

当搜索词为空时,我得到了同样的错误。 一旦我确定它不是空的,错误就消失了。 通过搜索词,我指的是getFromLocationName方法的第一个参数。

似乎对我有用的是在模拟器上登录 Google 帐户。 之后可能还需要重新启动。

就我而言,问题似乎是我快速连续多次调用地理编码器。 去抖动请求修复了它。

更新:

现在问题似乎已经解决了。 我不确定问题是否出在我的身上,所以如果你在这篇文章之前遇到了这个问题,重新运行你的应用程序,看看它现在是否有效。

如果它仍然不起作用,这里是我自己做的“可能”使它起作用的东西:

  1. 我卸载并删除了与 Android Studio 相关的所有文件。 不是项目文件)。
  2. 然后我重新安装了 Android Studio,并重新打开了该项目。
  3. 运行应用程序时(我使用的是 Android Studio 的内置模拟器),我使用了不同的虚拟设备和设备 API。 这次我在 Pixel 上运行它,使用 API 23,x86_64。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM