Создание MapView и добавление маркера программным способом приводит к исключению нулевого указателя во фрагменте

Я пытаюсь создать MapView программно и добавить MarkerPosition, как показано ниже:

MapView mapView = new MapView(getActivity());
((ViewGroup) rootView).addView(mapView);

GoogleMap googleMap = mapView.getMap();
googleMap.addMarker(new MarkerOptions()
        .position(new LatLng(
                Double.parseDouble(
                        mEvent.getEventInfo().mEventData.mLat),
                Double.parseDouble(
                        mEvent.getEventInfo().mEventData.mLng)))
        .title("Marker"));

Файл манифеста:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

<permission
    android:name="com.example.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />

<uses-permission android:name="com.example.permission.MAPS_RECEIVE" />

Я получаю следующую ошибку:

java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference

4 ответа

Решение

Потому что ваш googleMap еще не загружен означает ноль, и вы добавляете маркер на нем, что вызывает сбой. лучше использовать mapView.getMapAsync(context); скорее, чем mapView.getMap(); и реализовать этот метод

    @Override
    public void onMapReady(final GoogleMap map) {
        if(map != null){
        // you are ready to add marker here        
        }
    }

Карта Google теперь должна быть загружена асинхронно, добавив MapFragment в ваше представление, а затем поработайте над ним. Нечто подобное будет работать:

public class MainActivity extends Activity implements OnMapReadyCallback {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_activity);


        MapView mapView = new MapView(this);
        ((LinearLayout) findViewById(R.id.mapWrapper)).addView(mapView);
        mapView.getMapAsync(this);

    }

    @Override
    public void onMapReady(GoogleMap map) {

        map.addMarker(new MarkerOptions()
                .position(new LatLng(0, 0))
                .title("Marker"));
    }

}

С этим макетом

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapWrapper"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

</LinearLayout>

Пусть ваша деятельность реализует OnMapReadyCallback и добавит маркер в функцию OnMapReady().

См. https://developers.google.com/maps/documentation/android-api/start

Оказывается, на Google Play версии сервисов 11.8.0onCreatea() а также onResume() обязательно видеть MapView:

@Override public void setupMap(LatLng latLng) {
    if (mapView == null) {
      mapView = new MapView(getActivity());
      rootLayout.addView(mapView);
      mapView.onCreate(Bundle.EMPTY);
    }
    mapView.getMapAsync(map -> {
      map.clear();
      map.addCircle(MapUtil.makeDefaultGreenCircle(getActivity(), latLng));
    });
  }

@Override public void onResume() {
    super.onResume();
    mapView.onResume();
  }
Другие вопросы по тегам