MapFragment или MapView getMap() возвращает null на Lollipop

Я давно использую Google Maps API v2 на версиях Android 4.x без проблем. Теперь я установил последнюю сборку Lollipop на свои устройства Nexus (5 и 7), пытаясь материализовать приложение.

Хочу отметить, что на KitKiat все нормально, а проблема, которую я описываю, возникает только на Lollipop.

В моем исходном коде XML я использую MapFragment (версия библиотеки Google Play Services 6.1.11).

<fragment android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:name="com.google.android.gms.maps.MapFragment"/>

В коде Java я переопределяю метод OnPause() для доступа к карте:

GoogleMap map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

В этой строке выбрасывается исключение NullPointerException. В отладчике приложение может найти фрагмент, но не может вернуть GoogleMap. Я также пытался использовать MapView. Он также выдает ноль. Самое странное для меня то, что карта загружается без проблем в самом приложении, но в коде я не могу добраться до нее, чтобы работать с ней.


comment
Я бы проверил, не является ли это проблемой времени (фрагмент еще не создан). Попробуйте получить Фрагмент после некоторой задержки для эксперимента.   -  person Yaroslav Mytkalyk    schedule 27.10.2014
comment
Ответ на этот вопрос содержится в этой ссылке stackoverflow.com/a/22624155/706833 Надеюсь, это поможет;)   -  person iGoDa    schedule 27.10.2014
comment
@DoctororDrive - безуспешно пробовал 3-секундный цикл.   -  person mroczis    schedule 27.10.2014


Ответы (4)


У меня была точно такая же проблема, но это то, что сработало для меня:

Замените это...

GoogleMap map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

с этим...

GoogleMap map = getMapFragment().getMap();

затем подсунуть этого плохого мальчика и дать ему вихрь...

private MapFragment getMapFragment() {
    FragmentManager fm = null;

    Log.d(TAG, "sdk: " + Build.VERSION.SDK_INT);
    Log.d(TAG, "release: " + Build.VERSION.RELEASE);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        Log.d(TAG, "using getFragmentManager");
        fm = getFragmentManager();
    } else {
        Log.d(TAG, "using getChildFragmentManager");
        fm = getChildFragmentManager();
    }

    return (MapFragment) fm.findFragmentById(R.id.map);
}
person Rhisiart    schedule 28.12.2014
comment
Большое спасибо. Наконец, это сделало работу для меня. - person Kartik Sharma; 25.01.2015
comment
Это известная проблема на Lollipop? - person Jay Sidri; 10.02.2015
comment
Идеальный ответ. Спасибо! - person edgarmiro; 13.02.2015
comment
@Rhisiart спасибо за ваш ответ. Я хочу знать еще кое-что. После использования этого кода.. как мы будем обрабатывать backstack с этим фрагментом в панели навигации ... bcz после использования этого кода onbackstack не работает с этим фрагментом. - person Deep Singh; 18.07.2015
comment
@DeepSingh без подробностей, все, что я могу вам сказать, это то, что мой фрагмент расширяет com.google.android.gms.maps.MapFragment и размещается в android.support.v13.app.FragmentTabHost вместе с двумя другими android.widget.TabHost $TabSpec в android.app.Activity с таргетингом на android:targetSdkVersion=22. Вы можете увидеть его в действии в этом приложении (выберите «Найти события природы» или «Найти события» в панели навигации) — play.google.com/store/apps/ - person Rhisiart; 18.07.2015
comment
Я хотел бы +1 несколько раз к этому ответу - person Shubham Chaudhary; 21.07.2015
comment
Я пытаюсь реализовать это решение, но оно говорит, что getChildFragmentManager не определен. Я внутри Activity. Кто-нибудь, помогите мне, пожалуйста? - person Frildoren; 25.11.2015
comment
Чувак, ты сэкономил мне время. Большое спасибо - person Ramachandra Reddy Avula; 22.06.2016

Google теперь сделал более удобный способ получить карту, используя следующий метод

    myMapFragment.getMapAsync(new OnMapReadyCallback) {
         @Override
         public void onMapReady(GoogleMap googleMap) {
             myMap = googleMap;
         }
    });
person Exception    schedule 27.04.2015
comment
Это был правильный ответ в моем случае. Принятый ответ, по-видимому, предполагает, что MapFragment имеет значение null, что не так в соответствии с вопросом (в вопросе MapFragment не равен нулю, но возвращаемое значение getMap() равно null). - person BoD; 04.05.2015

Похоже, это может быть проблема с targetSdkVersion 21: https://code.google.com/p/android-developer-preview/issues/detail?id=1947

Однако у меня сработало переключение на getChildFragmentManager():

findFragmentById для SupportMapFragment возвращает значение null в Android Studio

person bubastis    schedule 24.11.2014

Пробовали ли вы isGooglePlayServicesAvailable, чтобы проверить, почему он возвращает значение null? null имеет много причин для getmap, попробуйте использовать это, чтобы проверить, почему он дает null

person iGoDa    schedule 27.10.2014
comment
Да, я сделал. Наконец, я решил свою проблему, повторно реализовав MapView. MapFragment вообще не работает. - person mroczis; 27.10.2014
comment
@mroczis Можете ли вы просто описать мне, как вы это исправили? - person itsmewajid; 28.10.2014
comment
В конце концов, я использовал MapView, настроил его жизненный цикл (вызов mMapView.onCreate() для метода активности onCreate(), mMapView.onPause() для активности onPause() и т. д.), и это сработало. MapFragment, кажется, не присоединяется к FragmentManager на Lollipop. - person mroczis; 28.10.2014