Не удается получить широту и долготу из Google Maps с помощью Retrofit

Я определил класс модели вместе с интерфейсом внутри него. Код выглядит следующим образом:

public class MapModel {
    MapContract.Presenter mPresenter;
    private Location mResLocation;
    private static final String TAG = MapModel.class.getSimpleName();

    public MapModel(MapContract.Presenter presenter) {
        mPresenter = presenter;
    }
    public static WebServiceInterface WebServiceInterface = RetrofitServiceGenerator.create(WebServiceInterface.class);


    public void queryAddress(String address) throws IOException {

        WebServiceInterface .lookupAddress(Constants.GOOGLE_API_KEY, address).enqueue(
                new Callback<Result>() {
                    @Override
                    public void onResponse(Call<Result> call, Response<Result> response) {


                        mResLocation = response.body().getGeometry().getLocation();


 Log.i(TAG, "onResponse: " + response.toString());
                            Log.i(TAG, "Location : " + mResLocation.getLat() + " : " + mResLocation.getLat());
                            mPresenter.onSearchSuccess(mResLocation);
                        }



                  @Override
                    public void onFailure(Call<Result> call, Throwable t) {mPresenter.onSearchFailed("Search failed");
                    }
                }
        );
    }
    public interface WebServiceInterface {

        @GET("json")
        Call<Result> lookupAddress(@Query("key") String apiKey, @Query("address") String searchTerm);
    }

}

Мой модифицированный генератор выглядит следующим образом:

public class RetrofitServiceGenerator {
    public static <S> S create(Class<S> serviceClass) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor)
                .readTimeout(30, TimeUnit.SECONDS)
                .connectTimeout(30, TimeUnit.SECONDS).build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://maps.googleapis.com/maps/api/geocode/")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
//                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        return retrofit.create(serviceClass);
    }
}

У меня проблема в том, что когда я вызываю метод queryAddress, кажется, что он возвращает null. Я создал объекты POJO для результата json, который я получаю, используя http://www.jsonschema2pojo.org/ . Вы можете увидеть полный код, а также класс классов POJO здесь. Я получаю следующее сообщение об ошибке:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Double sematec.mehdi.mymap.webmodels.Location.getLat()' on a null object reference Я думаю, что мой запрос правильный, поскольку журнал okhttp показывает для него правильный ответ json. Значит, виновник где-то в другом месте. Кто-нибудь знает, где я ошибаюсь?


person codezombie    schedule 26.01.2018    source источник
comment
показать, какие данные вы получаете в ответ   -  person Vladyslav Matviienko    schedule 26.01.2018
comment
@SpirosI.Oikonomakis, почему бы тебе не опубликовать ответ? Похоже, ваше уведомление верно.   -  person Vladyslav Matviienko    schedule 26.01.2018
comment
@VladMatvienko только за быстрый ответ.   -  person Spiros I. Economakis    schedule 26.01.2018


Ответы (2)


Проблема в том, что вы регистрируете широту/долготу, прежде чем установить объект из ответа. Эта линия

Log.i(TAG, "Location : " + mResLocation.getLat() + " : " + mResLocation.getLat());

должен идти после того, как вы установите объект из ответа.

Так должно быть:

mResLocation = response.body().getGeometry().getLocation();
Log.i(TAG, "Location : " + mResLocation.getLat() + " : " + mResLocation.getLat());
person Spiros I. Economakis    schedule 26.01.2018
comment
Все еще не работает. Та же ошибка. Пожалуйста, смотрите обновленный пост. - person codezombie; 26.01.2018

Наконец-то я нашел источник проблемы. Если вы посмотрите на веб-модели, там также есть класс GoogleMapModel. Вызывающий метод должен возвращать этот тип. Далее мы извлечем из него информацию о местоположении. Итак, код становится:

public class MapModel {
    MapContract.Presenter mPresenter;
    private Location mResLocation;
    private static final String TAG = MapModel.class.getSimpleName();

    public MapModel(MapContract.Presenter presenter) {
        mPresenter = presenter;
    }
    public static WebServiceInterface WebServiceInterface = RetrofitServiceGenerator.create(WebServiceInterface.class);


    public void queryAddress(String address) throws IOException {

        WebServiceInterface .lookupAddress(Constants.GOOGLE_API_KEY, address).enqueue(
                new Callback<GoogleMapModel>() {
                    @Override
                    public void onResponse(Call<GoogleMapModel> call, Response<GoogleMapModel> response) {
                        mResLocation = response.body().getResults().get(0).getGeometry().getLocation();
                        mPresenter.onSearchSuccess(mResLocation);
                    }

                    @Override
                    public void onFailure(Call<GoogleMapModel> call, Throwable t) {mPresenter.onSearchFailed("Search failed");
                    }
                }
        );
    }
    public interface WebServiceInterface {

        @GET("json")
        Call<GoogleMapModel> lookupAddress(@Query("key") String apiKey, @Query("address") String searchTerm);
    }

}
person codezombie    schedule 26.01.2018