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 ответов
ОБНОВИТЬ:
Кажется, проблема решена сейчас. Я не уверен, была ли проблема когда-либо на моем конце, поэтому, если у вас была эта проблема до этого поста, перезапустите ваше приложение и посмотрите, работает ли оно сейчас.
Если это все еще не работает, вот то, что я сделал сам, что могло бы заставить его работать:
- Я удалил и удалил все файлы, связанные с Android Studio. (НЕ файлы проекта).
- Затем я переустановил Android Studio и снова открыл проект обратно.
- При запуске приложения (я использую встроенный эмулятор 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 вещи, чтобы убедиться в:
- Как отмечают многие здесь (и в документации по Android здесь), все, что связано с
Geocoder
должно быть сделано отдельно от основного потока вашего приложения. Чтобы поддержать мое утверждение, вот цитата из документации Android: "Метод является синхронным и может занять много времени для его работы, поэтому не следует вызывать его из основного потока пользовательского интерфейса (UI) вашего приложения."
Теперь лучше всего использовать IntentService
Для этой задачи, как в официальной документации, приведен пример. Тем не менее, этот человек попробовал это с AsyncTask в Java, и он работал очень хорошо (обратите внимание, что их задача с geocoder
было намного менее интенсивно). Поэтому я настоятельно рекомендую использовать Anko's doAsync
метод и реализовать любой код, касающийся Geocoder
внутри.
Если возможно, используйте физическое устройство вместо эмулятора. Эмулятор в Android Studio доставлял мне много хлопот и не давал информацию об ошибке, которая нужна мне для решения проблемы.
Переустановите приложение на физическом устройстве и несколько раз отключите кэши / перезапустите проект.
Также убедитесь, что у вас хорошее сетевое соединение, и оно включено на вашем устройстве.
Сегодня (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();
У меня возникла та же проблема, и я не знал, в чем проблема. Вообще... До недавнего времени я стал замечать, что эта проблема возникает на реальном устройстве, когда я настраивал прокси. Когда я использовал 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 на сеть и обратно.