mapFragment.getMapAsync(this) - NullPointerExcepti

2019-01-17 06:25发布

I am using com.google.android.gms:play-services-maps:7.5.0 version of Google Maps services. When trying to call the below I get java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this); //error

    return inflater.inflate(R.layout.fragment_example_map, container, false);
}

fragment_example_map.xml file:

<FrameLayout 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="app.ExampleMap">

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

13条回答
混吃等死
2楼-- · 2019-01-17 07:01

use this.

GoogleMap gooleMap;

     ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap map) {
            googleMap = map;
           }
查看更多
做自己的国王
3楼-- · 2019-01-17 07:04

You are attempting to find a fragment before it exists. You indicate that the layout that has the fragment is fragment_example_map.xml. However, you are trying to find the map fragment before you inflate that layout file. This will not work.

Beyond that, you appear to be trying to get at the map fragment from inside another fragment, in that fragment's onCreateView() method. I do not know why you are nesting fragments here, as it seems like it will make your code more complex and more fragile for no obvious benefit.

查看更多
可以哭但决不认输i
4楼-- · 2019-01-17 07:05

My comment in maps with fragment , first you should refrenece your view as you will call something from it , this is why I inflate my view first
View view = inflater.inflate(R.layout.activity_maps, null, false);

Second call child fragment manager this.getChildFragmentManager() instead of getActivity().getSupportFragmentManager()

Here is the full example to view map

import android.os.Bundle;
import android.support.annotation.Nullable;
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.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class ClinicFragment extends Fragment implements OnMapReadyCallback {

    private GoogleMap mMap;

    public static ClinicFragment newInstance() {
        ClinicFragment fragment = new ClinicFragment();
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_maps, null, false);

        SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        return view;
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}

required permission

<permission
    android:name="your.package.name.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />
<uses-permission android:name="your.package.name.permission.MAPS_RECEIVE"/>

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

plus feature element

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

most import google maps key

<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="your_key_here" />

Update add this meta data if you face Error inflating class fragment

<meta-data 
      android:name="com.google.android.geo.API_KEY"  
      android:value="your_key_here" />

summery for mainfest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.package.name" >
// permission here

 <application
        android:name=".Activities.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

    // feature element 
    // maps key

  </application>

</manifest>

activity_maps.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.imaadv.leaynik.ClinicFragment" />
查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-17 07:07

this works for me:

SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this); 
查看更多
smile是对你的礼貌
6楼-- · 2019-01-17 07:10

replace this code

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

and

if (googleMap == null) {
        mapFrag =  (MapFragment)getFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }else{
        GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

    }
查看更多
【Aperson】
7楼-- · 2019-01-17 07:11

If your are using android:name="com.google.android.gms.maps.MapFragment" in your fragment then change your code with:

MapFragment mapFragment1 = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
        mapFragment1.getMapAsync(this);

However if your are using android:name="com.google.android.gms.maps.SupportMapFragment" in your fragment then use this code:

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
查看更多
登录 后发表回答