android - 在 Android 中使用 GoogleMaps 出现 NullPointerException

标签 android google-maps maps

我的代码在我的代码中的这一行抛出 NullPointerException:

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

我可以看到它在 LogCat 中抛出异常。我已经多次尝试解决这个问题,并且我已经阅读了该论坛上的所有类似问题。我尝试了一些解决方案,但没有成功。当我注释掉该行时,我会显示 Google map ,但是当我尝试在代码中获取该 fragment 时,我仍然遇到相同的异常。

这是我的代码:

package cs.exmpl;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.CameraUpdate;
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.model.LatLng;

public class MainActivity extends ActionBarActivity {
    private GoogleMap map;
    private final LatLng loc=new LatLng(566544, 556554);

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

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

        //SupportMapFragment mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
       // map = mapFrag.getMap();



            map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        CameraUpdate up=CameraUpdateFactory.newLatLngZoom(loc, 14);
        map.animateCamera(up);






        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

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

}

这是我的 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="cs.exmpl.MainActivity$PlaceholderFragment" >

    <TextView
        android:id="@+id/header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

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

</RelativeLayout>

最佳答案

getMap() 可能返回 null

引用文档

A GoogleMap can only be acquired using getMap() when the underlying maps system is loaded and the underlying view in the fragment exists. This class automatically initializes the maps system and the view; however you cannot be guaranteed when it will be ready because this depends on the availability of the Google Play services APK. If a GoogleMap is not available, getMap() will return null.

在初始化 GoogleMap 对象之前检查 Google Play 服务的可用性。

检查主题检查 Google Play 服务

http://developer.android.com/training/location/retrieve-current.html

编辑:

tools:context="cs.exmpl.MainActivity$PlaceholderFragment"

当您在 Activity 中初始化它时,MapFragment 看起来也处于 fragment 布局中。使用MapView跟随

Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment

或者扩展MapFragment而不是Fragment

编辑3:

示例:

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cs.exmpl.MainActivity"
    tools:ignore="MergeRootFrame" />

fragment_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="cs.exmpl.MainActivity$PlaceholderFragment" >

    <TextView
        android:id="@+id/header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

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


</RelativeLayout>

MainActivity.java

public class MainActivity extends ActionBarActivity {

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

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        MapView mapView;
        GoogleMap map;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_main, container, false);
        // Gets the MapView from the XML layout and creates it

        MapsInitializer.initialize(getActivity());


        switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) )
        {
        case ConnectionResult.SUCCESS:
          Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT).show();
          mapView = (MapView) v.findViewById(R.id.map);
          mapView.onCreate(savedInstanceState);
          // Gets to GoogleMap from the MapView and does initialization stuff
          if(mapView!=null)
          {
          map = mapView.getMap();
          map.getUiSettings().setMyLocationButtonEnabled(false);
          map.setMyLocationEnabled(true);
          CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
          map.animateCamera(cameraUpdate);
          }
          break;
        case ConnectionResult.SERVICE_MISSING: 
          Toast.makeText(getActivity(), "SERVICE MISSING", Toast.LENGTH_SHORT).show();
          break;
        case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: 
          Toast.makeText(getActivity(), "UPDATE REQUIRED", Toast.LENGTH_SHORT).show();
          break;
        default: Toast.makeText(getActivity(), GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()), Toast.LENGTH_SHORT).show();
        }




        // Updates the location and zoom of the MapView

        return v;
        }

        @Override
        public void onResume() {
        mapView.onResume();
        super.onResume();
        }
        @Override
        public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        }
        @Override
        public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
        }
        }

}

list

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cs.exmpl"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/> 

     <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"/>
     <!-- The following two permissions are not required to use
     Google Maps Android API v2, but are recommended. -->
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="cs.exmpl.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
               <meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="YOUR API KEY FROM GOOGLE API CONSOLE"/>
        <meta-data android:name="com.google.android.gms.version"
          android:value="@integer/google_play_services_version" />
    </application>

</manifest>

固定在设备上

enter image description here

关于android - 在 Android 中使用 GoogleMaps 出现 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23764931/

相关文章:

jquery - 在 jvectormap 中设置各个区域的样式

javascript - 如何在 Javascript 中获取一个国家/地区的坐标?

android - 在 CameraSource 上创建点击焦点 - Android 二维码检测

android - 在 Android 中从地理围栏调用 Activity

java - 将字符串值从一个函数传递到另一个函数而不将该字符串作为参数传递

android - 正在添加 TableRow 但不显示

android - 如何在android中获得ClusterManager点击和ClusterManager项目点击

iphone - 如何从 iPhone 中的 UIWebView 获取触摸位置经纬度值?

javascript - 如何向 Google map 中的国家/地区名称添加标签?

Javascript:在 Map() 与 Object 中找到最高值