Google Map Android API v2 : GoogleMap is null



我正在尝试探索使用MapView类进行GoogleMap显示,但没有运气,因为大多数代码示例都使用我不想要的MapFragment。

我正在使用谷歌地图Android API v2。

起初,只是为了从谷歌的例子中进行测试,我设法让典型的法线贴图显示出来。

public class POnlineMapView extends Activity {
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.online_map_activity);
    }
}

上面的代码运行良好,表明一切都已正确设置。

我现在尝试使用 MapView 类来操作显示设置,例如中心点,但似乎每次尝试获取 GoogleMap 对象时我都会获得一个空对象。为什么会这样?

public class POnlineMapView extends Activity {
    private MapView myMapView;
    private GoogleMap map;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myMapView = new MapView(getApplicationContext());
        Bundle b = getIntent().getExtras();
        double longitude = b.getDouble("longitude");
        double latitude = b.getDouble("latitude");
        setContentView(R.layout.online_map_activity);
        map = myMapView.getMap();
        CameraUpdate center= CameraUpdateFactory.newLatLng(new LatLng(latitude,longitude));
        CameraUpdate zoom=CameraUpdateFactory.zoomTo(17);
        map.moveCamera(center); //this gives a NullPointerException, probably due to the myMapView.getMap() method?
        map.animateCamera(zoom);    
    }
}

检查Google Play服务是否已安装(和更新)

查看 Google 地图 Android API v2 抛出 GooglePlayServicesNotAvailableException, 过期, SupportMapFragment.getMap() 返回 null

另请阅读 https://developers.google.com/maps/documentation/android/map(验证地图可用性部分)

这似乎是一个老问题,但我在尝试使用 MapView 时遇到了同样的问题。

假设您已经正确导入了Google Play服务库,您必须检查您是否可以访问Google服务,您可以在onCreate方法中执行此操作,并且必须初始化Google Maps Android AP。 您可以通过将以下代码添加到onCreate方法中来执行此操作。

try {
        MapsInitializer.initialize(this);
    } catch (GooglePlayServicesNotAvailableException e) {
        Log.e("Address Map", "Could not initialize google play", e);
    }
switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) )
{
  case ConnectionResult.SUCCESS:
      Toast.makeText(getApplicationContext(), "SUCCESS", Toast.LENGTH_SHORT).show();
      break;
  case ConnectionResult.SERVICE_MISSING: 
      Toast.makeText(getApplicationContext(), "SERVICE MISSING", Toast.LENGTH_SHORT).show();
      break;
  case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: 
      Toast.makeText(getApplicationContext(), "UPDATE REQUIRED", Toast.LENGTH_SHORT).show();
      break;
  default: Toast.makeText(getApplicationContext(), GooglePlayServicesUtil.isGooglePlayServicesAvailable(this), Toast.LENGTH_SHORT).show();
}

如果你成功了,那么到目前为止一切都在工作。您还必须实现活动lyfecycle的mothod,并在以下每个方法中调用地图视图的相应方法:

@Override
protected void onResume() {
    myMapView.onResume();
    super.onResume();
}
@Override
protected void onPause() {
    myMapView.onResume();
    super.onPause();
}
@Override
protected void onDestroy() {
    myMapView.onDestroy();
    super.onDestroy();
   //((MapView)findViewById(R.id.mapView)).onDestroy();
}
@Override
public void onLowMemory() {
    super.onLowMemory();
    myMapView.onLowMemory();
}

最后,您必须检查是否已将Google Maps API密钥添加到清单文件中:

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

您可以在此处找到获取密钥的说明:https://developers.google.com/maps/documentation/android/start#installing_the_google_maps_android_v2_api

编辑:忘了提,您还必须在清单文件上设置应用程序权限

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

这必须在应用程序块内设置...

谢谢,你终于给了我一个以编程方式初始化地图的线索,我监督它是多么愚蠢:)

好吧,有时没有使用MapFragment(或SupportMapFragment)的选项,即当您想使用片段中的地图时!在使用选项卡(ActionBar)时,这实际上是一种非常常见的情况,其中模式是使用片段。因此,每个选项卡都有自己的片段,并且在地图的片段中,您想要膨胀布局,其中包含MapFragment的片段,瞧 - 祝你好运!

现在,根据MapView规范,没有办法说不鼓励或弃用使用MapView,那么为什么我不应该使用它呢?我不希望在没有SDK支持的情况下维护嵌套片段(即使是最近的支持lib v13似乎也有错误,并且不支持布局中的嵌套片段),因此使用MapView对我来说变成了KISS。

下面是我使用的CustomMapFragment与布局膨胀(允许复杂布局)和嵌入式地图一起使用,欢迎您使用。您可能还希望从支持库而不是 SDK 扩展片段。

onCreateView() 方法会膨胀布局(只需提供您自己的布局),并期望布局具有 id 为"mapViewHolder"的视图组(相对布局、线性布局等),地图视图将在布局创建时附加到其中。该活动必须实现 CustomMapFragment.Handler 接口,否则将抛出 ClassCastException。

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import R;
public class AppMapFragment extends Fragment {
  /*
   * to interact with activity
   */
  public static interface Handler {
    void onMapResume(GoogleMap map);
  }
  private Handler handler;
  private MapView mapView;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    try {
      // initialize explicitely, since we're working with MapView (not MapFragment)
      MapsInitializer.initialize(getActivity());
      this.mapView = new MapView(getActivity());
      this.mapView.onCreate(savedInstanceState);
    } catch (GooglePlayServicesNotAvailableException e) {
      Toast.makeText(getActivity(), "Please install Google Play Store and retry again!", Toast.LENGTH_LONG).show();
      getActivity().finish();
    }
  }
  @Override
  public void onResume() {
    super.onResume();
    this.mapView.onResume();
    this.handler.onMapResume(this.mapView.getMap());
  }
  @Override
  public void onPause() {
    super.onPause();
    this.mapView.onPause();
  }
  @Override
  public void onDestroy() {
    super.onDestroy();
    this.mapView.onDestroy();
  }
  @Override
  public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    this.mapView.onSaveInstanceState(outState);
  }
  @Override
  public void onLowMemory() {
    super.onLowMemory();
    this.mapView.onLowMemory();
  }
  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
      this.handler = (Handler) activity;
    } catch (ClassCastException e) {
      throw new ClassCastException("Your activity has to implement the interface " + this.handler.getClass().getName());
    }
  }
  public AppMapFragment() {
  }
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_results_map, container, false);
    ((ViewGroup) rootView.findViewById(R.id.mapViewHolder)).addView(this.mapView);
    return rootView;
  }
}
MapFragment和MapView

之间的一个区别是,你必须手动管理MapView的生命周期,而MapFragment自己处理它。

您必须从父活动/片段的相应方法调用以下方法。

onCreate(Bundle)
onResume()
onPause()
onDestroy()
onSaveInstanceState()
onLowMemory()

我在Google Play服务的样本中使用RawMapViewDemoActivity验证了这一点,这些样本可以安装在Android SDK Manager的Extras部分。

该示例首先显示了地图,一旦我注释掉 mMapView.onXXX() 的 6 行,它就会显示一个空白页。

也许生命周期是我们随处可见的大多数示例使用MapFragment的原因。

试试这个方式:

  private MapView myMapView;   
  private GoogleMap map;  
      myMapView = (MapView) findViewById(R.id.map);     
      if (map == null) {     
                map = ((MapView) findViewById(R.id.map)).getMap();     
       }

我对地图视图也没有运气。
我确实有MapFragment的运气。

试试这个:

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
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.LatLng;
public class TestActivity extends FragmentActivity {
  SupportMapFragment mapFragment;
  GoogleMap map;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (mapFragment == null) {
      mapFragment = new SupportMapFragment();
      getSupportFragmentManager().beginTransaction()
          .add(android.R.id.content, mapFragment).commit();
    }
  }
  @Override
  protected void onResume() {
    super.onResume();
    setupMap();
  }
  private void setupMap() {
    if (map != null)
      return;
    map = mapFragment.getMap();
    if (map == null)
      return;
    doZoom();
  }
  private void doZoom() {
    if (map != null) {
      map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(45.424900,
          -75.694968), 17));
    }
  }
}

相关内容

  • 没有找到相关文章

最新更新