java.io.IOException: grpc потерпел неудачу

Когда я использую вызов 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 обновлены.

Заранее спасибо!

РЕДАКТИРОВАТЬ:

Кажется, проблема решена, вот мое решение.

29 ответов

Решение

ОБНОВИТЬ:

Кажется, проблема решена сейчас. Я не уверен, была ли проблема когда-либо на моем конце, поэтому, если у вас была эта проблема до этого поста, перезапустите ваше приложение и посмотрите, работает ли оно сейчас.

Если это все еще не работает, вот то, что я сделал сам, что могло бы заставить его работать:

  1. Я удалил и удалил все файлы, связанные с Android Studio. (НЕ файлы проекта).
  2. Затем я переустановил Android Studio и снова открыл проект обратно.
  3. При запуске приложения (я использую встроенный эмулятор Android Studio) я использовал другое виртуальное устройство и API устройства. На этот раз я запустил его на Pixel с API 23, x86_64.

Я могу воспроизвести эту проблему (java.io.IOException: grpc failed), когда на моем реальном устройстве нет подключения к Интернету.

Как пишет Google, вы не должны вызывать этот метод в потоке пользовательского интерфейса

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

Я исправил эту проблему, запустив эту операцию в новом Thread, а затем, если мне нужно обновить вид интерфейса, я сделаю это на runOnUiThread

Эта проблема появилась у меня (хотя я делаю запрос в фоновом потоке), но только в эмуляторе Android Studio. Странный обходной путь, который исправляет это для меня, - включить, а затем выключить режим полета!

Может быть, у вас есть эта проблема только в Genymotion и эмулятор андроид студии. Я столкнулся с той же проблемой с Genymotion и Android Studio Emulator, а затем я проверил его в Android реального устройства. Это работает хорошо для меня. Вы проверяли это на реальном устройстве?

Я сталкиваюсь с этой проблемой на устройстве Android 4.4.2 несколько раз. Для меня решение состоит в том, чтобы просто перезагрузить телефон. Нет обновления кода нет Android Studio удалить.

Это происходило и на моем телефоне Samsung S7 Edge с установленным Oreo. Это происходило только тогда, когда у меня был включен режим полета (не всегда - означает, что что-то могло быть кэшировано в некоторых точках). Я не исследовал внутренности 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 года я все еще получаю это время от времени, когда отслеживаю свой собственный http-трафик через прокси. Выключите и проблема исчезла.

SomeTimes Geocoder не работает, когда широта и долгота содержат более 3 десятичных знаков, или можно сказать, что 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();

Хотя довольно поздно в этом вопросе, вот ответ для пользователей Kotlin.

Я наткнулся на это java.io.IOException: grpc failed ошибка при использовании геокодера getFromLocation функция. Я использовал Google Pixel 2 в качестве моего тестового устройства (под управлением Android 9).

Есть 3 вещи, чтобы убедиться в:

  1. Как отмечают многие здесь (и в документации по Android здесь), все, что связано с Geocoder должно быть сделано отдельно от основного потока вашего приложения. Чтобы поддержать мое утверждение, вот цитата из документации Android: "Метод является синхронным и может занять много времени для его работы, поэтому не следует вызывать его из основного потока пользовательского интерфейса (UI) вашего приложения."

Теперь лучше всего использовать IntentService Для этой задачи, как в официальной документации, приведен пример. Тем не менее, этот человек попробовал это с AsyncTask в Java, и он работал очень хорошо (обратите внимание, что их задача с geocoder было намного менее интенсивно). Поэтому я настоятельно рекомендую использовать Anko's doAsync метод и реализовать любой код, касающийся Geocoder внутри.

  1. Если возможно, используйте физическое устройство вместо эмулятора. Эмулятор в Android Studio доставлял мне много хлопот и не давал информацию об ошибке, которая нужна мне для решения проблемы.

  2. Переустановите приложение на физическом устройстве и несколько раз отключите кэши / перезапустите проект.

Также убедитесь, что у вас хорошее сетевое соединение, и оно включено на вашем устройстве.

Сегодня (2017-09-16) моя Android Studio (2.3.3) получила обновление для сервисов Google Play до версии 44. Проблема была исправлена ​​позже. Никаких изменений кода или настроек с моей стороны.

Я думаю, что это зависит от расположения устройства. потому что карта Google иногда не работает должным образом в какой-то области. Я из Ирана, и у меня также была эта проблема на реальном устройстве и эмуляторе. Через некоторое время я решил использовать приложение vpn, и оно работало на реальном устройстве и эмуляторе. потому что приложение vpn изменило мой IP-адрес.

Я сталкивался с этой проблемой, когда получал список адресов с помощью метода geocoder.getFromLocation(), проблема в том, что получение списка адресов по широте, долготе занимает время или на некоторых медленных устройствах это занимает больше времени, а иногда это также дает мне java-io- IOException-КПГР-не удалось.

Я исправляю эту проблему с помощью 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);

Метод ViewModel

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

После некоторых исследований выясните, как решить эту проблему, в моем случае все способы, такие как вставка кода в новый Thread или используйте GeocodingApi не работает, просто измените версию библиотеки местоположений

в моем случае проблема была в последней версии библиотеки местоположений:

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

измените его на:

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

и проблему реши!

Наконец-то я понял, как это работает, используя следующую конфигурацию для SDK версии 25, Инструменты сборки и эмулятор API.

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

Также используется Google API версии 11.0.2.

Об этой проблеме уже сообщалось, вы можете найти другие сообщения в стеке, рассказывающие об этом. Вот комментарий к проблеме Google с некоторыми из различных способов сбоя геокодера. Я советую вам окружить свою часть кода попробовать и поймать, чтобы ваше приложение не останавливалось.

В Wi-Fi соединение работает нормально, но в 3G или 4G соединение не работает.

Использование прокси

По своему опыту могу сказать, что эта ошибка вызвана Geocoderс getFromLocation()метод. Так что не делайте следующего:

  • Не вызывайте этот метод в основном потоке. Это заморозит пользовательский интерфейс, и если что-то, что зависит от результата этого метода, выйдет из строя. Разберитесь с этим делом.
  • Когда нет подключения к Интернету, снова IOExeptionбудет брошен. Опять же, все, что зависит от результата этого метода, выйдет из строя. Разберитесь с этим делом.

AOA! Поверните режим точности устройства Gps в момент (только GPS) другого варианта, а затем попробуйте......

у меня сработали настройки вот так, я посту вы их тоже можете найти на эмуляторах

Привет, у меня возникла ошибка «grpc failed» после возврата к старому проекту / тесту телефона.

Мой код вызывал метод getFromLocation() и просто терпел неудачу. читая и играя в течение нескольких часов, я подумал, что проверю, будут ли работать карты Google, он показал мое местоположение на пустой карте, Wi-Fi был отключен, поэтому я включил Wi-Fi, карта работала нормально.

Повторно протестированное приложение, и вуаля мой метод getFromLocation() работает, так что должно быть что-то липкое в области служб определения местоположения ....

В моем случае проблема заключалась в том, что я вызывал геокодер слишком много раз подряд. Отказ от запросов исправил это.

В моем случае я удалил AVD и переустановил его, и все было в порядке.

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

Размер адресов обычно равен 0. Это может быть результатом сбоя пиковых адресов, поэтому их можно пометить как «Неизвестно» или «по умолчанию».

Я получил ту же ошибку, когда поисковый запрос был пуст. Как только я убедился, что он не пуст, ошибка исчезла. По поисковому запросу я имею в виду первый аргумент getFromLocationNameметод.

Это сработало для меня.

SomeTimes Geocoder не работает, когда широта и долгота содержат более 3 десятичных знаков, или можно сказать, что 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();

Источник: https://github.com/xamarin/Essentials/issues/759

У меня возникла та же проблема, и я не знал, в чем проблема. Вообще... До недавнего времени я стал замечать, что эта проблема возникает на реальном устройстве, когда я настраивал прокси. Когда я использовал charles на MAC, проблем с этим не было, но когда я начал использовать MITM в Linux, эта проблема начинала появляться каждый раз без исключения. Возможно потребуется дополнительно настроить MITM. Но суть в том, что если вы отключите прокси, все будет в порядке.

Так что посмотри на это, может быть.

Это работает для меня, если представить Geocoder как синглтон для приложения, а не создавать его каждый раз. Обязательно вызовите Geocoder.getFromLocationName() из рабочего потока.

Например:

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

class SomeClass {

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

В моем случае я просто включил (разрешение предоставлено) настройку Положение из приложения.

Кажется, я решил эту проблему, открыв верхнюю панель инструментов телефона и просто переключившись между Wi-Fi и сетью, я предполагаю, что операционная память на всех виртуальных устройствах установлена ​​на 2 ГБ ОЗУ, и поиск местоположения просто использует слишком много, поэтому я увидел пропускать кадры и местоположение без возможности поиска. Так что, если он сбрасывает эту ошибку, просто переключитесь с Wi-Fi на сеть и обратно.

Другие вопросы по тегам