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
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'
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();
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>
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.
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:
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.
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());
}
}
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>