web-dev-qa-db-fra.com

Fragment de Google Maps retournant nul à l'intérieur d'un fragment

J'ai donc un fragment vide qui contient un fragment de carte. Chaque fois que j'essaie d'activer le fragment contenant la carte, mon application se bloque et renvoie une erreur de pointeur nul sur cette ligne:

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

Message d'erreur complet:

Java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.Android.gms.maps.GoogleMap com.google.Android.gms.maps.MapFragment.getMap()' on a null object reference
            at com.collusion.serviceassistant.ReturnVisitDetails.onViewCreated(ReturnVisitDetails.Java:39)
            at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:904)
            at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:1062)
            at Android.app.BackStackRecord.run(BackStackRecord.Java:684)
            at Android.app.FragmentManagerImpl.execPendingActions(FragmentManager.Java:1447)
            at Android.app.FragmentManagerImpl$1.run(FragmentManager.Java:443)
            at Android.os.Handler.handleCallback(Handler.Java:733)
            at Android.os.Handler.dispatchMessage(Handler.Java:95)
            at Android.os.Looper.loop(Looper.Java:136)
            at Android.app.ActivityThread.main(ActivityThread.Java:5001)
            at Java.lang.reflect.Method.invoke(Native Method)
            at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:785)
            at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:601)

Voici mon code de fragment:

import Android.app.Activity;
import Android.app.Dialog;
import Android.net.Uri;
import Android.os.Bundle;
import Android.app.Fragment;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

import com.google.Android.gms.common.ConnectionResult;
import com.google.Android.gms.common.GooglePlayServicesUtil;
import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.MapFragment;
import com.google.Android.gms.maps.MapView;
import com.google.Android.gms.maps.model.BitmapDescriptorFactory;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.Marker;
import com.google.Android.gms.maps.model.MarkerOptions;


public class ReturnVisitDetails extends Fragment {

    static final LatLng HAMBURG = new LatLng(53.558, 9.927);
    static final LatLng KIEL = new LatLng(53.551, 9.993);
    private GoogleMap map;
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_return_visit_add, container, false);
        return rootView;
    }

    public void onViewCreated(View view, Bundle savedInstanceState)
    {
        // Get a handle to the Map Fragment
        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
                .getMap();
        Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
                .title("Hamburg"));
        Marker kiel = map.addMarker(new MarkerOptions()
                .position(KIEL)
                .title("Kiel")
                .snippet("Kiel is cool")
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.ic_launcher)));

        // Move the camera instantly to hamburg with a zoom of 15.
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

        // Zoom in, animating the camera.
        map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
    }
}

Et ma disposition XML de fragment parent:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context="com.collusion.serviceassistant.ReturnVisitDetails"
    Android:background="#009688">


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

</RelativeLayout>

Quelqu'un a une idée pourquoi le fragment de carte retourne nul?

EDIT: Alors maintenant, j'ai ce code pour initialiser la carte:

MapFragment mapFragment = new MapFragment();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.add(R.id.rl_map_container, mapFragment).commit();
        map = mapFragment.getMap();
        Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
                .title("Hamburg"));
        Marker kiel = map.addMarker(new MarkerOptions()
                .position(KIEL)
                .title("Kiel")
                .snippet("Kiel is cool")
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.ic_launcher)));

        // Move the camera instantly to hamburg with a zoom of 15.
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

        // Zoom in, animating the camera.
        map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

Et il renvoie toujours une valeur de pointeur nulle

18
axtscz

Ce problème m'est arrivé lorsque j'ai essayé de porter mon projet Eclipse sur Android Project Studio.

Java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.Android.gms.maps.GoogleMap com.google.Android.gms.maps.SupportMapFragment.getMap()' on a null object reference

Je l'ai utilisé avec une activité de fragment comme celle-ci:

((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapToday)).getMap();

Cependant, le problème était que, auparavant, j'utilisais une version spécifique des services Google Play (4.3.23).

Mais la version Gradle sélectionne la version la plus récente (compile 'com.google.Android.gms:play-services:+')

J'ai essayé une autre version spécifique comme (6.1.71). Mais donnait toujours une exception de point nul.

J'ai utilisé la même ancienne version qu'avant et cela a fonctionné.

compile 'com.google.Android.gms:play-services:4.3.23'

Cela fonctionne pour moi comme une solution temporaire. Cependant, ce sera un problème lorsque je devrai mettre à jour vers une nouvelle bibliothèque de services de lecture.

Il semble qu'il n'y ait pas de bibliothèque de cartes spécifique avec cette version disponible pour la construction Gradle lorsque j'essaie comme ceci:

compile 'com.google.Android.gms:play-services-maps:4.3.23'
10
kalan

J'ai résolu le problème. cette ligne quand j'ai un viseur:

mMap = ((SupportMapFragment) MainActivity.fragmentManager
                .findFragmentById(R.id.mapView)).getMap();

vous devez changer pour ceci:

  mMap = ((SupportMapFragment) getChildFragmentManager()
            .findFragmentById(R.id.mapView)).getMap();
26
Cabezas

Votre classe s'étend de Fragment et vous utilisez un Fragment déclaré dans la disposition, mais le fragment imbriqué ne fonctionne que lorsqu'il est ajouté dynamiquement.

Vous avez donc deux options:

1) Extension à partir de FragmentAcivity au lieu de Fragment et application des méthodes appropriées.

2) Ajoutez dynamiquement le Fragment, comme suit:

// ReturnVisitDetails

MapFragment mapFragment = new MapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.rl_map_container, mapFragment).commit();

//Disposition

<FrameLayout
        Android:id="@+id/rl_map_container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

- MIS À JOUR -

Un exemple complet pour utiliser Google Maps dans un Fragment:

// TestFragmentActivity

public class TestFragmentActivity extends Android.support.v4.app.FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_fragment_activity);
    }

}

// TestFragment

public class TestFragment extends Android.support.v4.app.Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.test_fragment, container, false);

        CustomMapFragment mapFragment = new CustomMapFragment();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.add(R.id.map_container, mapFragment).commit();
        return rootView;
    }

}

// CustomMapFragment

public class CustomMapFragment extends com.google.Android.gms.maps.SupportMapFragment {

    private final LatLng HAMBURG = new LatLng(53.558, 9.927);

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        GoogleMap googleMap = getMap();
        googleMap.addMarker(new MarkerOptions().position(HAMBURG).title("Hamburg"));
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
    }

}

//test_fragment_activity.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">

    <fragment
        Android:id="@+id/map"
        class="your_package.TestFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

</RelativeLayout>

//test_fragment.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">

    <FrameLayout
        Android:id="@+id/map_container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

</RelativeLayout>
21
Víctor Albertos

J'ai cherché beaucoup de discussions à ce sujet car j'avais le même problème avec les anciens services Google Play. Comme Victor a dit que votre classe s'étend de fragment et qu'elle doit utiliser un autre fragment défini dans la disposition, la meilleure approche sera donc d'utiliser getChildFragmentManager() au lieu de getSupportFragmentManager().

Aussi getMap() method is deprecated maintenant comme mentionné dans google docs. Veuillez vous y référer pour en savoir plus: - https://developers.google.com/Android/reference/com/google/Android/gms/maps/MapFragment.html#getMap ()

Vous trouverez ci-dessous le code de travail que j'ai testé sur divers appareils d'anciens services de jeux. Cela générera le message par défaut en cas d'appareil ayant des services google play plus anciens et en cas d'objet de GoogleMap retourne null:

class MyFragment extends Fragment
{
      SupportMapFragment myMapFragment;
    GoogleMap myMap;
    View convertView;
    FragmentManager fm;
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {

    convertView=inflater.inflate(R.layout.mymap,null);
    fm=getChildFragmentManager();
        myMapFragment=(SupportMapFragment) fm.findFragmentById(R.id.myMapId);


        // here instead of using getMap(), we are using getMapAsync() which returns a callback and shows map only when it gets ready.
        //it automatically checks for null pointer or older play services version, getMap() is deprecated as mentioned in google docs.


        myMapFragment.getMapAsync(new OnMapReadyCallback() {

            @Override
            public void onMapReady(GoogleMap googlemap) {
                // TODO Auto-generated method stub
                myMap=googlemap;
                startMap();
            }
        });


    return convertView;
    }

}

Voir ce fil pour plus d'informations.

8
Mrigank

Serait-ce un problème de migration vers une version sdk cible de 21? Si c'est le cas, la solution suivante peut vous intéresser:

MapFragment ou MapView getMap () renvoie null sur Lollipop

7
Rhisiart

Le problème peut être lié au fait que votre targetSdkVersion est supérieur à la version de Android Support Library utilisée.

C'était mon cas, dans l'un des projets sur lesquels nous travaillions targetSdkVersion était 21, tandis que la version de la bibliothèque de support était 19.0.0. Changer targetSdkVersion en 19 a résolu le problème.

0
syntagma

Je peux faire face au même problème mais finalement je peux résoudre cette erreur. Maintenant, la carte montre correctement ...

=> Appelez la méthode initilizeMap () dans Fragment au sein d'une méthode onCreateView () ...

=> Déclarez la variable globale comme,

private GoogleMap googleMap;

 private void initilizeMap() {
    try {

        // Changing marker icon
        // marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_marker_icon)));

        // adding marker
        if (googleMap == null) {
            googleMap = ((MapFragment)getActivity().getFragmentManager()
                    .findFragmentById(R.id.map)).getMap();

            // create marker
            MarkerOptions marker = new MarkerOptions().position(
                    new LatLng(latitude, longitude)).title(
                    "YourCare");

            // Changing marker icon
            MarkerOptions icon = marker.icon(BitmapDescriptorFactory
                    .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
            // adding marker

            LatLng latLng = new LatLng(latitude, longitude);
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
                    latLng, 15);
            googleMap.animateCamera(cameraUpdate);
            // locationManager.removeUpdates(this);

            googleMap.addMarker(marker);
            googleMap.setMyLocationEnabled(true);
            // check if map is created successfully or not
            if (googleMap == null) {
                Toast.makeText(getActivity(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            }

        }
    } catch (Exception e) {
        System.out.print("Error :" + e.getMessage());
    }

}
0
sathish

Essayez d'utiliser SupportMapFragment au lieu de MapFragment. Ce code fonctionne pour moi pour un fragment, viens de l'essayer:

import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.SupportMapFragment;
import com.google.Android.gms.maps.model.BitmapDescriptorFactory;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.Marker;
import com.google.Android.gms.maps.model.MarkerOptions;

public class MapFragment extends Fragment {

private GoogleMap map;
static final LatLng HAMBURG = new LatLng(53.558, 9.927);
static final LatLng KIEL = new LatLng(53.551, 9.993);

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_map, container,
            false);

    // Get a handle to the Map Fragment
    map = ((SupportMapFragment) getFragmentManager().findFragmentById(
            R.id.map)).getMap();
    Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
            .title("Hamburg"));
    Marker kiel = map.addMarker(new MarkerOptions()
            .position(KIEL)
            .title("Kiel")
            .snippet("Kiel is cool")
            .icon(BitmapDescriptorFactory
                    .fromResource(R.drawable.ic_launcher)));

    // Move the camera instantly to hamburg with a zoom of 15.
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));

    // Zoom in, animating the camera.
    map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

    return rootView;
}
}

et votre mise en page:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity" >

<fragment
    Android:id="@+id/map"
    Android:name="com.example.test.MapFragment"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    class="com.google.Android.gms.maps.SupportMapFragment" />

</RelativeLayout>
0
user1282637