Невозможно получить широту и долготу из Карт Google, используя Retrofit
Я определил класс Model вместе с интерфейсом внутри него. Код выглядит следующим образом:
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
, кажется, вернуть ноль. Я создал объекты 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. Так что виновник где-то еще. Кто-нибудь знает, где я не прав?
2 ответа
Проблема в том, что вы записываете широту / долготу, прежде чем установить объект из ответа. Эта линия
Log.i(TAG, "Location : " + mResLocation.getLat() + " : " + mResLocation.getLat());
должен идти после того, как вы установите объект из ответа.
Так и должно быть:
mResLocation = response.body().getGeometry().getLocation();
Log.i(TAG, "Location : " + mResLocation.getLat() + " : " + mResLocation.getLat());
Я наконец нашел источник проблемы. Если вы посмотрите на веб-модели, есть также класс 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);
}
}