MapFragment返回null

时间:2013-10-01 05:46:44

标签: android google-maps

mMapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mMapFragment == null) {
          mMapFragment = SupportMapFragment.newInstance();


            // Then we add it using a FragmentTransaction.
            FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.add(MapLay.getId(), mMapFragment, MAP_FRAGMENT_TAG);
             fragmentTransaction.commit();


            mMap=mMapFragment.getMap();

此代码地图可见但无法访问地图

MMAP = mMapFragment.getMap();显示空值错误如何解决此问题

6 个答案:

答案 0 :(得分:17)

更新1: getMap() 已弃用

最好使用MapFragment/SupportMapFragment import com.google.android.gms.maps.*; import com.google.android.gms.maps.model.*; import android.app.Activity; import android.os.Bundle; public class MapPane extends Activity implements OnMapReadyCallback { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map_activity); MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap map) { LatLng sydney = new LatLng(-33.867, 151.206); map.setMyLocationEnabled(true); map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 13)); map.addMarker(new MarkerOptions() .title("Sydney") .snippet("The most populous city in Australia.") .position(sydney)); } } 方法。示例如何使用下面显示的方法(从getMapAsync()复制)。

GoogleMap

引用Google的documentation

  

GoogleMap只能在底层使用getMap()获取   加载了地图系统,并且片段中的基础视图存在。   该类自动初始化地图系统和视图;   但是,因为这样,你就无法保证准备就绪   取决于Google Play服务APK的可用性。如果一个   GoogleMap不可用,getMap()将返回null。

在您的代码中,您会在提交MapFragment后立即检索MapFragment。等到活动完全加载GoogleMap后,您就可以获得GoogleMap

也许,您可以使用界面将MapFragmentActivity传递到public class MyMapFragment extends SupportMapFragment { private MapCallback callback; public void setMapCallback(MapCallback callback) { this.callback = callback; } public static interface MapCallback { public void onMapReady(GoogleMap map); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if(callback != null) callback.onMapReady(getMap()); } } public class MyActivity extends Activity implements MyMapFragment.MapCallback { // ......... @Override public void onCreate(Bundle onsavedInstanceState) { mMapFragment = (MyMapFragment) getSupportFragmentManager() .findFragmentByTag(MAP_FRAGMENT_TAG); // We only create a fragment if it doesn't already exist. if (mMapFragment == null) { mMapFragment = MyMapFragment.newInstance(); mMapFragment.setMapCallback(this); // This activity will receive the Map object once the map fragment is fully loaded // Then we add it using a FragmentTransaction. FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.add(MapLay.getId(), mMapFragment, MAP_FRAGMENT_TAG); fragmentTransaction.commit(); } else { mMapFragment.setMapCallback(this); // This activity will receive the Map object once the map fragment is fully loaded } @Override public void onMapReady(GoogleMap map) { // Do what you want to map } } ,就像这样。

{{1}}

答案 1 :(得分:2)

导入部分

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;

在oncreate中

SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map); 
    mMap = mapFragment.getMap();

和Xml Part

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

确保你已经放入

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

<application></application>标记内。

并在数据文件中提供这些权限

<permission
          android:name="packagename.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
    <uses-permission android:name="packagename.permission.MAPS_RECEIVE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <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"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>    
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>

答案 2 :(得分:1)

您的xml应该有SupportMapFragment

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

答案 3 :(得分:1)

我把这段代码解决了这个问题:

@Override
public void onPause() {

    Fragment fragment = (getFragmentManager().findFragmentById(R.id.map_tab));  
    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
    ft.remove(fragment);
    ft.commit();
    super.onPause();
}

或者我将此代码放在onCreate

if (mView != null) {
     ViewGroup parent = (ViewGroup) mView.getParent();
     if (parent != null) {
         parent.removeView(mView);
     }
 }
 try {
  mView = inflater.inflate(R.layout.tab_map_layout, container, false);
 } catch (InflateException e) {

 }

答案 4 :(得分:1)

按照2013年10月1日6:05的@Glenn--评论创建此源代码。

My Implementation正在用MapFragment替换SupportMapFragment并支持Google Maps Version 2

我想再次记住:

  

只有在加载基础地图系统并且片段中的基础视图存在时,才能使用getMap()获取GoogleMap。该类自动初始化地图系统和视图;但是,当它准备就绪时,您无法保证,因为这取决于Google Play服务APK的可用性。如果GoogleMap不可用,则getMap()将返回null。

我的实施:

的AndroidManifest.xml

<!-- Permissions -->

<!-- Used by the Google Maps API to download map tiles from Google Maps servers. -->
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

<!-- Allows the Google Maps API to check the connection status in order to determine whether data can be downloaded. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- Allows the Google Maps API to cache map tile data in the device's external storage area. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<!-- Allows the Google Maps API to use WiFi or mobile cell data (or both) to determine the device's location. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<!-- Allows the Google Maps API to use the Global Positioning System (GPS) to determine the device's location to within a very small area. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- Permissions -->

<!-- Required OpenGL ES 2.0. for Maps V2 -->
<!-- 
    The Google Maps Android API uses OpenGL ES version 2 to render the map. 
    If OpenGL ES version 2 is not installed, your map will not appear. 
    sWe recommend that you add the following <uses-feature> element as a child of the <manifest> element in AndroidManifest.xml:
 -->
 <uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <!-- Google Play Services -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <!-- Goolge Maps API Key -->
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="AIzaSyATC4WBLLewjdwYDFVTnJH8hA18gG_GgvY" />

</application>

activity_main.xml中

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="mapa.bg.MapaMainActivity" 
    android:background="#ccc">

    <!-- Google Map Container -->
    <RelativeLayout 
        android:id="@+id/google_map_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <!-- Google Map Container -->
</RelativeLayout>

ApplicationMapFragment.java

public class ApplicationMapFragment extends MapFragment {

    private MapCallback callback;

    public void setMapCallback(MapCallback callback) {
        this.callback = callback;
    }

    public static interface MapCallback {
        public void onMapReady(GoogleMap map);
    }

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if(callback != null) callback.onMapReady(getMap()); 
    }

    /**
     * Initialize default Google Maps Options for our Application
     * @return GoogleMapOptions
     */
    public GoogleMapOptions initializeGoogleMapsOptions() {
        GoogleMapOptions googleMapOptions = new GoogleMapOptions()
            .mapType(GoogleMap.MAP_TYPE_HYBRID);

        return googleMapOptions;
    }
}

MainActivity.java

public class MainActivity extends Activity implements ApplicationMapFragment.MapCallback {

    // Get Class Name
    private static String TAG = MainActivity.class.getName();

    // Create a new Map fragment
    private ApplicationMapFragment mapFragment;

    // Google Map Fragment Name
    private static String MAP_FRAGMENT_TAG = "google_maps_fragment";

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

        try {
                initilizeMapFragment();
        } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "Google Maps can't be loaded", e);
        }
    }

    /**
     * Initialize a new Map Fragment
     */
    private void initilizeMapFragment() {

        // Try to get Map Fragment
        mapFragment = (ApplicationMapFragment) getFragmentManager()
                .findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mapFragment == null) {
            mapFragment = new ApplicationMapFragment();
            mapFragment.initializeGoogleMapsOptions();

            // This activity will receive the Map object once the map fragment is fully loaded
            mapFragment.setMapCallback(this);

            // Then we add it using a FragmentTransaction.
            FragmentTransaction fragmentTransaction =
                    getFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.google_map_container, mapFragment, MAP_FRAGMENT_TAG);
            fragmentTransaction.commit();
        } else {
            // This activity will receive the Map object once the map fragment is fully loaded
            mapFragment.setMapCallback(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap map) {
        Log.d(TAG, "Google Map is loaded");

        MarkerOptions marker = new MarkerOptions()
            .position(new LatLng(10, 10))
            .title("Hello World");

        map.addMarker(marker);
    }
}

答案 5 :(得分:0)

真的是hackish解决方案但是,因为给出了糟糕的片段API ...

请注意,我是从自定义View执行此操作并使用(Activity)getContext()

访问Activity
            addOnLayoutChangeListener(new OnLayoutChangeListener(){
                @Override
                public void onLayoutChange(View v, int left, int top,
                        int right, int bottom, int oldLeft, int oldTop,
                        int oldRight, int oldBottom) {

                    GoogleMap map = mapFragment.getMap();

                    if (map != null) {
                         //Do stuff
                    }else{
                         removeOnLayoutChangeListener(this);
                    }
                }
            });