Подтвердить что ты не робот

Почему Android Geocoder выбрасывает исключение "Service not Available"?

Приложение использует объект Geocoder. Он отлично работает на моем складе Froyo Nexus One. Но затем я запускаю то же приложение на другом устройстве (планшет Advent Vega 10), также запускающий Froyo), и я получаю это исключение: Служба недоступна. Метод, который я использую, getFromLocationName(), я строю против Android 1.6 API Google.

Мне известно о проблеме, когда это исключение выбрано на эмуляторе, но я подозреваю, что это другое. Зачем его бросать на одно устройство, на котором работает Froyo, но не на другое?

Приложение представляет собой приложение для местоположения, а поскольку планшет не имеет GPS или мобильной сети, в сценарии, когда соединение Wi-Fi не предоставляет местоположение, пользователь должен вручную указать его, поэтому не сможете использовать объект Geocoder - плохая новость.

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

Надеемся, что в будущем выпуске Android будет включать "местоположение по умолчанию на уровне ОС" для устройств, отличных от Geocoder, поэтому приложения, ориентированные на местоположение, работают из коробки на таких устройствах, как Google TV.

4b9b3361

Ответ 1

Я попросил Google Reto Meier подтвердить, что моя теория верна, и он сказал: "Правильно. Геокодер является частью дополнения Google API, которое не является частью AOSP".

Таким образом, любое устройство, которое не поставляется с Play Маркет, приложениями GMail и т.д., также будет отсутствовать на сервере Geocoder.

Ответ 2

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

Ответ 3

Некоторые устройства не имеют поддержки для Geocoder, поэтому вам нужно создать собственный геокодер.

В принципе, вам нужно создать асинхронную задачу для запроса google для адреса и обработать ответ json.

Используя aquery, я делаю что-то вроде этого:

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

У меня была такая же проблема. Я использовал следующую функцию.

Примечание:

Используйте 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;
}