向谷歌地图添加标记时出现空指针异常



我正在尝试在我的安卓应用程序中向谷歌地图添加一个标记。但是我在运行应用程序时收到空点异常。我看不出我的代码可能在哪里出错。

这是我使用过的代码

GoogleMap googleMap = null;
            MapFragment fm = (MapFragment) (activity.getFragmentManager())
                    .findFragmentById(R.id.map);
            googleMap = fm.getMap();
            googleMap.addMarker(new MarkerOptions()
            .position(new LatLng(7.421226f,80.401264f))
            .title("Hello world"));

日志猫

12-31 16:51:54.667: E/AndroidRuntime(10191): FATAL EXCEPTION: main
12-31 16:51:54.667: E/AndroidRuntime(10191): java.lang.NullPointerException
12-31 16:51:54.667: E/AndroidRuntime(10191):    at com.fortuna.cinemalk.adapter.ViewPageAdapter.instantiateItem(ViewPageAdapter.java:201)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:829)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at android.support.v4.view.ViewPager.populate(ViewPager.java:979)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at android.support.v4.view.ViewPager.populate(ViewPager.java:911)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:440)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at com.fortuna.cinemalk.TheaterDetailFragment$BackGround.onPostExecute(TheaterDetailFragment.java:148)
12-31 16:51:54.667: E/AndroidRuntime(10191):    at com.fortuna.cinemalk.TheaterDetailFragment$BackGround.onPostExecute(TheaterDetailFragment.java:1)

1) 片段可能为空。

除非在布局中定义了地图片段,否则您无法在 onCreate 中找到它。(如果是这种情况,请告诉我,我会更新答案。

2)片段尚未加载地图。

这是更有可能的情况。您可以拥有 MapFragment 的实例,但还不必具有 GoogleMap 的实例。最新的Google Play服务SDK(v6.5.87)为您提供了MapFragment.getMapAsync(OnMapReadyCallback)的方法。回调将在GoogleMap实例可用时立即运行。只有这样你才能使用它。

显然,问题出在地图本身而不是标记上。

首先,检查您用作库的谷歌播放服务版本。如果您有 6.5 版本(2014 年 12 月发布)之前的内容,请查看以下代码(Google Play 服务示例中的信用),以确保您没有空地图对象。

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.example.mapdemo;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
/**
 * This shows how to create a simple activity with a map and a marker on the map.
 * <p>
 * Notice how we deal with the possibility that the Google Play services APK is not
 * installed/enabled/updated on a user's device.
 */
public class BasicMapDemoActivity extends FragmentActivity {
    /**
     * Note that this may be null if the Google Play services APK is not available.
     */
    private GoogleMap mMap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.basic_demo);
        setUpMapIfNeeded();
    }
    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }
    /**
     * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
     * installed) and the map has not already been instantiated.. This will ensure that we only ever
     * call {@link #setUpMap()} once when {@link #mMap} is not null.
     * <p>
     * If it isn't installed {@link SupportMapFragment} (and
     * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
     * install/update the Google Play services APK on their device.
     * <p>
     * A user can return to this FragmentActivity after following the prompt and correctly
     * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
     * have been completely destroyed during this process (it is likely that it would only be
     * stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
     * method in {@link #onResume()} to guarantee that it will be called.
     */
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }
    /**
     * This is where we can add markers or lines, add listeners or move the camera. In this case, we
     * just add a marker near Africa.
     * <p>
     * This should only be called once and when we are sure that {@link #mMap} is not null.
     */
    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }
}



我强烈推荐的另一个解决方案是获取最新的谷歌播放服务库(查看此处)。然后,您必须根据Google的本指南更改代码,使用getMapAsync()(而不是getMap())和回调,只要地图准备好使用,您就可以做任何事情,而不会再麻烦。

您是否检查过地图实际加载?我猜空指针异常实际上来自地图,而不是来自在其上放置标记。

本教程是开始使用谷歌地图(包括处理这样的异常)的绝佳指南:http://www.vogella.com/tutorials/AndroidGoogleMaps/article.html

getMap 已弃用,请改用 getMapAsync。您的活动需要实现 OnMapReadyCallback 接口,因此您可以在 onMapReady 方法中添加标记。

从文档:

getMap() 此方法已弃用。请改用getMapAsync(OnMapReadyCallback)。回调方法为您提供了一个 GoogleMap 实例,该实例保证为非 null 并可供使用。

编辑:正如其他答案所提到的,getMap()现在实际上已经贬值了。

因此,不再推荐以下方法,但可能仍然有效。


首先,请确保您已将地图API密钥输入到您的AndroidManifest.xml

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

然后确保在布局中正确定义地图(请参阅下面的示例)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_height="fill_parent"
    android:layout_alignParentTop="true" />
 </RelativeLayout>   

完成后,您可以按如下方式访问地图

 android.support.v4.app.FragmentManager mFragmentManager = getSupportFragmentManager();
 final SupportMapFragment mMapFragment = (SupportMapFragment) mFragmentManager.findFragmentById(R.id.mapView);
 googleMap = mMapFragment.getMap();
  1. 首先使用此方法检查谷歌地图是否为空或非空 --> If(gMap!=null)
  2. 无论您是必须从url下载标记图标表单(还是)直接从url将标记图像添加到标记信息窗口中,都可能获得网络主线程异常。
  3. 网络主线程异常导致标记图像为空,因此您可能会在谷歌地图中获得空指针异常

溶液:

在 onCreate 方法中添加以下行

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);  

最新更新