我正在尝试使用MapView类进行GoogleMap显示,没有运气,因为大多数代码示例都使用了我不想要的MapFragment。
我正在使用Google Maps Android API v2。
首先,只是为了使用here from Google's example进行测试,我设法显示了典型的法线贴图。
public class POnlineMapView extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.online_map_activity);
}
}
上面的代码完美无缺,表明所有内容都已正确设置。
我现在正在尝试使用MapView类来操作显示设置,例如中心点,但似乎我每次尝试获取GoogleMap对象时都会获得一个null对象。为什么会这样?
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);
}
}
答案 0 :(得分:3)
检查是否已安装(并更新)Google Play服务
另请阅读https://developers.google.com/maps/documentation/android/map(验证地图可用性部分)
答案 1 :(得分:3)
这似乎是一个老问题,但我在尝试使用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();
}
如果你获得SUCCESS,那么到目前为止一切正常。 您还必须实现Activity lyfecycle的方法,并在每个方法中调用地图视图的相应方法:
@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密钥添加到Manifest文件中:
<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"/>
必须在应用程序块中设置...
答案 2 :(得分:3)
谢谢,你终于给了我一个以编程方式初始化地图的线索,我是多么愚蠢地监督它:)
好吧,有时没有选项可以使用MapFragment(或类似SupportMapFragment),即当您想要使用片段中的地图时!在处理模式使用片段的制表符(ActionBar)时,这实际上是一种非常常见的情况。所以你有每个标签你自己的片段,你想要给你的布局充气,你想要给你的布局充气,其中包含一个MapFragment的片段,等等 - 祝你好运!
现在,根据MapView规范,不鼓励使用MapView,不鼓励或弃用,为什么我不应该使用它?我不想在没有SDK支持的情况下维护嵌套片段(即使最近的支持lib v13似乎有bug,也不支持布局中的嵌套片段),所以使用MapView转向KISS。
下面是我使用的CustomMapFragment布局膨胀(允许复杂的布局)和嵌入式地图,欢迎您使用它。您可能还希望从support-lib而不是SDK扩展Fragment。
onCreateView()方法使布局膨胀(只是提供你自己的)并期望布局具有id为“mapViewHolder”的viewgroup(relativelayout,linearlayout等),其中mapView将在创建布局时附加到。该活动必须实现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;
}
}
答案 3 :(得分:1)
MapFragment和MapView之间的一个区别是你必须手动管理MapView的生命周期,而MapFragment自己负责管理它。
您必须从父Activity / Fragment的相应方法中调用以下方法。
onCreate(Bundle)
onResume()
onPause()
onDestroy()
onSaveInstanceState()
onLowMemory()
我在Google Play服务的示例中使用RawMapViewDemoActivity验证了这一点,可以安装在Android SDK Manager的Extras部分。
示例首先显示了地图,一旦我注释掉了mMapView.onXXX()的6行,它就显示了一个空白页。
也许生命周期是我们到处看到的大多数示例使用MapFragment的原因。
答案 4 :(得分:0)
尝试这种方式:
private MapView myMapView; private GoogleMap map; myMapView = (MapView) findViewById(R.id.map); if (map == null) { map = ((MapView) findViewById(R.id.map)).getMap(); }
答案 5 :(得分:0)
我也没有运气的地图视图。
我确实幸运地使用了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));
}
}
}