API Google Android для Android v2 выбрасывает GooglePlayServicesNotAvailableException, устаревший, SupportMapFragment.getMap () возвращает null

Я пытаюсь включить новый API Android Google Maps v2 в приложение, используя библиотеку поддержки Android. Я прошел через много итераций, чтобы попытаться найти работу, и теперь я сдался и подумал, что я должен спросить здесь.

Я пошел в API-консоль, создал проект, включил Google Maps API v2 для Android, создал необходимый отладчик KEY и вставил его в манифест. Нет проблем с проверкой подлинности или чего-либо подобного. Довольно уверен, что я сделал это правильно.

В папке libs моего проекта я поставил android-support-v4.jar (через проект правой android-support-v4.jar > Android-> Добавить библиотеку поддержки …). В Eclipse я сделал File-> Import-> Android-> Существующий код Android в рабочей области и импортировал последнюю версию (rev 3) android-sdk / google / google_play_services / libproject / google-play-services_lib. Затем я добавил его в качестве библиотеки зависимостей в свой проект (проект правой кнопкой мыши-> Свойства-> Android-> Добавить его как зависимость библиотеки внизу.

В моем манифесте я:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" ...> <permission android:name="myapp.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <All the uses-permission required like INTERNET, ACCESS_NETWORK_STATE, WRITE_EXTERNAL_STORAGE, FINE AND COARSE LOCATION, etc> <uses-permission android:name="myapp.permission.MAPS_RECEIVE"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> <application ...> ... <uses-library android:name="com.google.android.maps" /> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AI..."/> </application> 

В моем mainview.xml у меня есть:

 <fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="com.google.android.gms.maps.SupportMapFragment" /> 

Теперь на MainView.java у меня есть:

 import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; public class MainView extends FragmentActivity ... { private GoogleMap mMap; @Override protected void onResume() { ... Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map); SupportMapFragment mapFragment = (SupportMapFragment)fragment; mMap = mapFragment.getMap(); //PROBLEM: mMap is null here even though mapFragment is not } } 

Затем мне показалось, что мне, вероятно, нужно инициализировать фрагменты, поэтому я добавил в свой onCreate после настройки содержимого:

 //Fragments FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.map, SupportMapFragment.newInstance()); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.commit(); 

Тогда я сказал, может быть, это не поддержка SupportMapFragment но я действительно должен ссылаться на фактический фрагмент, и в моем onResume я сделал:

 Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map); SupportMapFragment mapFragment = (SupportMapFragment)fragment; //Fragments FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.map, mapFragment); transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); transaction.commit(); mMap = mapFragment.getMap(); 

mMap снова имеет значение null.

Затем я увидел, что есть класс MapsInitializer , поэтому я подумал, что, может быть, я должен назвать это первым.

Поэтому я добавил код перед тем, как получить фрагмент в приведенном выше коде:

 try { MapsInitializer.initialize(this); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); } 

При этом Logcat сообщил о предупреждении (строка 313 – MapsInitializer.initialize(this) ):

 com.google.android.gms.common.GooglePlayServicesNotAvailableException at com.google.android.gms.internal.nc(Unknown Source) at com.google.android.gms.internal.na(Unknown Source) at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source) at myapp.activities.MainView.inflateSelectedViewAndSetData(MainView.java:313) at myapp.activities.MainView.onClick(MainView.java:642) at android.view.View.performClick(View.java:3153) at android.view.View$PerformClick.run(View.java:12148) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:4615) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:491) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) at dalvik.system.NativeStart.main(Native Method) 

Во время моих попыток Logcat сообщит следующее предупреждение:

 Google Play services out of date. Requires 2010100 but found 1013 

Это может быть виновником, но я не нашел решения.

На данный момент у меня нет идей. Здесь я прочитал несколько тем здесь , здесь , но ни одно из предложений не разрешило проблему. В последнем они предлагают не включать зависимость проекта и просто включать файл jar. Ну, это не сработало ни с помощью google-play-services.jar из папки google-play-services_lib/libs ни с экспорта моей собственной банки из этого проекта.

Кстати, я работаю на реальном устройстве (2.3.5 и планшете с 3.2), а не на эмуляторе.

Любая помощь искренне ценится. 🙂

ОБНОВИТЬ:

Решение находится ниже кубитом.

Если экспортировать библиотечную зависимость, аккуратный способ не иметь дело с ней (что является болью при работе с репозиториями) – использовать FatJar и экспортировать проект google_play_services_lib (который я НЕ создал локальную копию, потому что, когда он обновляет Я не хочу повторно импортировать), и включить в ваш проект файл с избыточным содержимым в качестве другого файла jar. ПРИМЕЧАНИЕ. При выборе файлов jar для включения в жирную банку мне пришлось исключить файл annotations.jar поскольку он уже был предварительно включен и вызывает ошибки для дублирования. Теперь все, что мне нужно сделать, это включить google_play_services_rev_3.jar в папку с google_play_services_rev_3.jar моего проекта, и мне хорошо идти.

Solutions Collecting From Web of "API Google Android для Android v2 выбрасывает GooglePlayServicesNotAvailableException, устаревший, SupportMapFragment.getMap () возвращает null"

Загрузите и установите последние Google Play services из Play Маркета. По какой-то причине я не смог найти его, выполнив поиск. /extras/google/google_play_services/samples/maps образец приложения из SDK в папке /extras/google/google_play_services/samples/maps мне было предложено установить обновление и было отправлено в Play Store для этого.

Как описано в нижней части этой ссылки; http://developer.android.com/google/play-services/setup.html

И здесь приведен пример кода для правильной обработки;

 int checkGooglePlayServices = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { // google play services is missing!!!! /* Returns status code indicating whether there was an error. Can be one of following in ConnectionResult: SUCCESS, SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mActivity, 1122).show(); } 

У меня была такая же проблема в моем проекте. Решение очень просто, просто обработайте возможность того, что ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); Может вернуть null . Если вы будете обрабатывать null buid-in SupportMapFragment будет работать с устаревшими SupportMapFragment Google Play services out of date. И покажет вам, что вы установили локализованное сообщение карты и кнопку для обновления Службы Google Play точно так же, как @qubz рассказывает об этом в примерном проекте.

Код из образца:

 @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } /** * Sets up the map if it is possible to do so (ie, the Google Play services APK is correctly * installed) and the map has not already been instantiated.. This will ensure that we only ever * call {@link #setUpMap()} once when {@link #mMap} is not null. * <p> * If it isn't installed {@link SupportMapFragment} (and * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to * install/update the Google Play services APK on their device. * <p> * A user can return to this FragmentActivity after following the prompt and correctly * installing/updating/enabling the Google Play services. Since the FragmentActivity may not have been * completely destroyed during this process (it is likely that it would only be stopped or * paused), {@link #onCreate(Bundle)} may not be called again so we should call this method in * {@link #onResume()} to guarantee that it will be called. */ private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } /** * This is where we can add markers or lines, add listeners or move the camera. In this case, we * just add a marker near Africa. * <p> * This should only be called once and when we are sure that {@link #mMap} is not null. */ private void setUpMap() { mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker")); } 

И результат:

Введите описание изображения здесь

Как документация

GoogleMap может быть получен только с помощью getMap (), когда загружена базовая система карт и существует базовый вид в фрагменте. Этот класс автоматически инициализирует систему карт и представление; Однако вы не можете быть уверены, когда он будет готов, потому что это зависит от доступности APK сервисов Google Play. Если GoogleMap недоступен, getMap () вернет значение null. SupportMapFragment