Я работаю над интеграцией Google Maps в приложение, над которым я работаю, и у меня было довольно неприятное время. Несмотря на это, я наконец получил SupportMapFragment, отображающий карту, и установил местоположение и уровень масштабирования.
Вот функциональные биты моего кода:
@Override
public void onActivityCreated( Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
Location location = BundleChecker.getExtraOrThrow( KEY_LOCATION, new Bundle[] { savedInstanceState, getArguments() } );
setLocation( location );
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
setMapFragment( new SupportMapFragment() );
getActivity().getSupportFragmentManager().beginTransaction().add( R.id.location_detail_mapFrame, getMapFragment() ).commit();
}
populateAddress();
attachButtonListeners();
Runnable initMap = new Runnable() {
@Override
public void run() {
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
try {
GoogleMap map = getMapFragment().getMap();
LatLng latLng = getLocation().getAddress().getLatLng( getActivity() );
CameraUpdate update = CameraUpdateFactory.newLatLngZoom( latLng, DEFAULT_MAP_ZOOM );
map.animateCamera( update );
}
catch (IOException e) {
Log.e( TAG, e.getMessage(), e );
Toast.makeText( getActivity(), "Unable to find location", Toast.LENGTH_SHORT ).show();
}
}
}
};
Handler handler = new Handler();
handler.postDelayed( initMap, 200 );
}
Кроме того, я написал простой метод удобства, чтобы получить LatLng из моей модели Address, которую вы также можете критиковать:
/*
* Convenience method to easily check if there is a valid lat & lng in this address
*/
public boolean hasLatLng() {
return getLatitude() != null && getLongitude() != null;
}
/*
* Convenience method for use with Google Maps API
*/
public LatLng getLatLng( Context context ) throws IOException {
LatLng latLng = null;
if ( hasLatLng() ) {
latLng = new LatLng( getLatitude(), getLongitude() );
}
else {
String locationString = getStreet() + ", " + AddressUtil.makeCityStateZipString( this );
Geocoder geoCoder = new Geocoder( context );
try {
List<android.location.Address> matches = geoCoder.getFromLocationName( locationString, 2 );
if ( matches != null && matches.size() > 0 ) {
double lat = matches.get( 0 ).getLatitude();
double lng = matches.get( 0 ).getLongitude();
latLng = new LatLng( lat, lng );
}
}
catch (IOException e) {
throw new IOException( e );
}
}
return latLng;
}
Я знаю, что этот код не идеален и нуждается в рефакторинге. Это мой первый опыт работы с Google Maps, поэтому, пожалуйста, не стесняйтесь предлагать предложения относительно того, как я могу это сделать. У меня возникло много проблем при попытке использовать MapFragment как в моем макете XML, поэтому я создаю его программно.
Сердце вопроса: Я получал некоторые ложные адресные данные с промежуточного сервера, и это привело к тому, что метод getLatLng Address # возвращал значение null, которое вызвало исключение при вызове CameraUpdateFactory.newLatLngZoom. После того, как я получил это исключение, я больше не мог получать данные из Google. Теперь фрагмент карты пуст, и сообщения отображаются в logcat:
05-21 18: 11: 42.903: API Android для Android/Android (15747): не удалось связаться с серверами Google. Другая попытка будет сделана при установлении соединения.
05-21 18: 11: 43.093: E/API Google Maps для Android (15747): Не удалось загрузить карту. Ошибка при обращении к серверам Google. Вероятно, это проблема аутентификации (но может быть из-за сетевых ошибок).
Я создал новый ключ api и заменил текущий в своем манифесте без изменений. Единственные изменения, которые я внес в вышеуказанный код, - это учет нулевого LatLng, и с тех пор я отменил эти изменения в бессмысленной попытке вернуть мой код в функциональное состояние.
Кроме того, чтобы сделать вещи немного странными, я построил проект с образцами карт, который входит в состав сервисов Google Play Services, и он отлично работает (имеет отдельный ключ API, кстати).
Что я мог сделать здесь неправильно? Могу ли я игнорировать что-то очевидное?