我是在Android上使用地图的初学者。当我尝试将以下语句添加到我的代码中时,我遇到了问题:
map = ((mapfragment) getfragmentmanager().findfragmentbyid(r.id.map)).getmap()
应用程序启动时会一直崩溃。有人可以帮我找到解决方案吗?
main.java
package com.example.myfirstapp;
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 final LatLng location= new LatLng(49.27645, -122.917587);
private GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
}
@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;
}
public void onClick_Search(View view) {
CameraUpdate update = CameraUpdateFactory.newLatLng(location);
map.animateCamera(update);
map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
}
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"
tools:context="com.example.myfirstapp.MainActivity$PlaceholderFragment" >
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_below="@+id/Search" />
<EditText
android:id="@+id/Longitude"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/Latitude"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/Latitude"
android:ems="10"
android:hint="@string/Longitude" />
<EditText
android:id="@+id/Latitude"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:ems="10"
android:hint="@string/Latitude" />
<Button
android:id="@+id/Search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="onClick_Search"
android:text="@string/search" />
</RelativeLayout>
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<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"/>
<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" >
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name="com.example.myfirstapp.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="AIzaSyCR9Zwp4m9nrKNWmfd1jAoeC8icski08_c" />
</application>
</manifest>
logcat的
05-16 12:07:10.600: E/AndroidRuntime(1007): FATAL EXCEPTION: main
05-16 12:07:10.600: E/AndroidRuntime(1007): Process: com.example.myfirstapp, PID: 1007
05-16 12:07:10.600: E/AndroidRuntime(1007): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myfirstapp/com.example.myfirstapp.MainActivity}: java.lang.NullPointerException
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread.access$800(ActivityThread.java:135)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.os.Handler.dispatchMessage(Handler.java:102)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.os.Looper.loop(Looper.java:136)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-16 12:07:10.600: E/AndroidRuntime(1007): at java.lang.reflect.Method.invokeNative(Native Method)
05-16 12:07:10.600: E/AndroidRuntime(1007): at java.lang.reflect.Method.invoke(Method.java:515)
05-16 12:07:10.600: E/AndroidRuntime(1007): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-16 12:07:10.600: E/AndroidRuntime(1007): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-16 12:07:10.600: E/AndroidRuntime(1007): at dalvik.system.NativeStart.main(Native Method)
05-16 12:07:10.600: E/AndroidRuntime(1007): Caused by: java.lang.NullPointerException
05-16 12:07:10.600: E/AndroidRuntime(1007): at com.example.myfirstapp.MainActivity.onCreate(MainActivity.java:27)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.Activity.performCreate(Activity.java:5231)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
05-16 12:07:10.600: E/AndroidRuntime(1007): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
05-16 12:07:10.600: E/AndroidRuntime(1007): ... 11 more
答案 0 :(得分:1)
看起来你想要Map
内的Fragment
。您需要使用MapView
或扩展MapFragment
本身。
http://developer.android.com/reference/com/google/android/gms/maps/MapView.html
你的min sdk是11.动作栏可以从api 11级获得。所以没有必要延长ActionBarActivity
。您可以扩展标准Activity
。
将片段中的布局更改为
<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"
tools:context="com.example.myfirstapp.MainActivity$PlaceholderFragment" >
<EditText
android:id="@+id/Longitude"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/Latitude"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/Latitude"
android:ems="10"
android:hint="@string/Longitude" />
<EditText
android:id="@+id/Latitude"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:ems="10"
android:hint="@string/Latitude" />
<Button
android:id="@+id/Search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="onClick_Search"
android:text="@string/search" />
<com.google.android.gms.maps.MapView
android:layout_above="@+id/Search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
/>
</RelativeLayout>
在你的片段中
public class MyFragment extends Fragment {
MapView mapView;
GoogleMap map;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment2, container, false);
// Initialize otheres view here
// Gets the MapView from the XML layout and creates it
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
Log.e("Address Map", "Could not initialize google play", e);
}
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();
}
}
编辑:
事实上,我没有看到片段。
所以改为
public class MainActivity extends Activity {
private final LatLng location= new LatLng(49.27645, -122.917587);
private GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
}
注意:getMap()
可以返回null。您应该在初始化Map对象之前检查google平台服务的可用性。
引用文档
GoogleMap只能在底层使用getMap()获取 加载了地图系统,并且片段中的基础视图存在。 该类自动初始化地图系统和视图; 但是,因为这样,你就无法保证准备就绪 取决于Google Play服务APK的可用性。如果一个 GoogleMap不可用,getMap()将返回null。
答案 1 :(得分:0)
这是因为 findViewById()在 activity_main 布局中进行搜索,而地图位于片段的布局 fragment_main 中。
在片段的onCreateView()
方法中移动该段代码
<强>例如强>
//...
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
Button buttonClick = (Button)rootView.findViewById(R.id.button);
buttonClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onButtonClick((Button) view);
}
});
请注意,现在您可以通过rootView视图访问它:
Button buttonClick = (Button)rootView.findViewById(R.id.button);
否则你会再次 NullPointerException 。