之前我使用过此代码,但现在我在恢复地图状态时遇到了一些错误。我从David Gassner的教程中得到了这段代码,现在我想再次使用它。我有点困惑,我把一些抛出的消息,以便追踪。 LogCat报告指出RESUME中的错误从此行开始任何人都知道如何解决这个问题?
map.animateCamera(update);
map.setMapType(mgr.getSavedMapType())
继承守则:
@Override
protected void onStop() {
super.onStop();
MapStateManager mgr = new MapStateManager(this);
mgr.saveMapState(mMap);
Toast.makeText(this, "Map State has been save?", Toast.LENGTH_SHORT).show();
}
@Override
protected void onResume() {
super.onResume();
MapStateManager mgr = new MapStateManager(this);
CameraPosition position = mgr.getSavedCameraPosition();
if (position != null) {
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
Toast.makeText(this, "entering Resume State", Toast.LENGTH_SHORT).show();
mMap.moveCamera(update);
mMap.setMapType(mgr.getSavedMapType());
}
}
public class MapStateManager {
private static final String LONGITUDE = "longitude";
private static final String LATITUDE = "latitude";
private static final String ZOOM = "zoom";
private static final String BEARING = "bearing";
private static final String TILT = "tilt";
private static final String MAPTYPE = "MAPTYPE";
private static final String PREFS_NAME ="mapCameraState";
private SharedPreferences mapStatePrefs;
public MapStateManager(Context context) {
mapStatePrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
public void saveMapState(GoogleMap mapMie) {
SharedPreferences.Editor editor = mapStatePrefs.edit();
CameraPosition position = mapMie.getCameraPosition();
editor.putFloat(LATITUDE, (float) position.target.latitude);
editor.putFloat(LONGITUDE, (float) position.target.longitude);
editor.putFloat(ZOOM, position.zoom);
editor.putFloat(TILT, position.tilt);
editor.putFloat(BEARING, position.bearing);
editor.putInt(MAPTYPE, mapMie.getMapType());
editor.commit();
}
public CameraPosition getSavedCameraPosition() {
double latitude = mapStatePrefs.getFloat(LATITUDE, 0);
if (latitude == 0) {
return null;
}
double longitude = mapStatePrefs.getFloat(LONGITUDE, 0);
LatLng target = new LatLng(latitude, longitude);
float zoom = mapStatePrefs.getFloat(ZOOM, 0);
float bearing = mapStatePrefs.getFloat(BEARING, 0);
float tilt = mapStatePrefs.getFloat(TILT, 0);
CameraPosition position = new CameraPosition(target, zoom, tilt, bearing);
return position;
}
public int getSavedMapType() {
return mapStatePrefs.getInt(MAPTYPE, GoogleMap.MAP_TYPE_NORMAL);
}
}
这是logcat的错误。我只包括红线。
> 01-07 12:51:46.145: E/AndroidRuntime(15770): FATAL EXCEPTION: main
01-07 12:51:46.145: E/AndroidRuntime(15770): java.lang.RuntimeException: Unable to resume activity {com.ourThesis.junieNegentien2015/com.ourThesis.junieNegentien2015.MainActivity}: java.lang.NullPointerException
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2936)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2400)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.access$600(ActivityThread.java:162)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.os.Handler.dispatchMessage(Handler.java:107)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.os.Looper.loop(Looper.java:194)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.main(ActivityThread.java:5371)
01-07 12:51:46.145: E/AndroidRuntime(15770): at java.lang.reflect.Method.invokeNative(Native Method)
01-07 12:51:46.145: E/AndroidRuntime(15770): at java.lang.reflect.Method.invoke(Method.java:525)
01-07 12:51:46.145: E/AndroidRuntime(15770): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
01-07 12:51:46.145: E/AndroidRuntime(15770): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
01-07 12:51:46.145: E/AndroidRuntime(15770): at dalvik.system.NativeStart.main(Native Method)
01-07 12:51:46.145: E/AndroidRuntime(15770): Caused by: java.lang.NullPointerException
01-07 12:51:46.145: E/AndroidRuntime(15770): at com.ourThesis.junieNegentien2015.MainActivity.onResume(MainActivity.java:183)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1190)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.Activity.performResume(Activity.java:5213)
01-07 12:51:46.145: E/AndroidRuntime(15770): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2923)
01-07 12:51:46.145: E/AndroidRuntime(15770): ... 12 more
@Tim Castelijns,下面是修改后的模式,但仍然无法正常工作,你能看看吗?
private SupportMapFragment mapFragment;
private GoogleMap map;
private Location mCurrentLocation;
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupMapIfNeeded();
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
}
private void setupMapIfNeeded() {
mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
if (mapFragment != null) {
mapFragment.getMapAsync(new OnMapReadyCallback()
{
@Override
public void onMapReady(GoogleMap map)
{
loadMap(map);
}
});
} else
{
Toast.makeText(this, "Error - Map Fragment was null!!", Toast.LENGTH_SHORT).show();
}
}
protected void loadMap(GoogleMap googleMap) {
map = googleMap;
if (map != null) {
// Map is ready
Toast.makeText(this, "Map Fragment was loaded properly!", Toast.LENGTH_LONG).show();
initListeners();
// map is loaded, trace your location
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
connectClient();
//calling resume state
resumeState(map);
} else {
Toast.makeText(this, "Error - Map was null!!", Toast.LENGTH_SHORT).show();
}
}
protected void connectClient() {
// Connect the client.
if (isGooglePlayServicesAvailable() && mGoogleApiClient != null) {
mGoogleApiClient.connect();
Toast.makeText(this, "Google API Client successfully connected", Toast.LENGTH_LONG).show();
}
}
/*
* Called when the Activity becomes visible.
*/
@Override
protected void onStart() {
super.onStart();
connectClient();
}
public void resumeState(GoogleMap googleMap) {
map = googleMap;
MapStateManager mgr = new MapStateManager(this);
CameraPosition position = mgr.getSavedCameraPosition();
if (position != null) {
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
Toast.makeText(this, "entering Resume State", Toast.LENGTH_LONG).show();
map.moveCamera(update);
map.setMapType(mgr.getSavedMapType());
}
}
/*
* Called when the Activity is no longer visible.
*/
@Override
protected void onPause() {
super.onPause();
MapStateManager mgr = new MapStateManager(this);
mgr.saveMapState(map);
Toast.makeText(this, "Map State has been save?", Toast.LENGTH_LONG).show();
}
@Override
protected void onResume() {
super.onResume();
setupMapIfNeeded();
}
@Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
Toast.makeText(this, "GPS location was found!", Toast.LENGTH_SHORT).show();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16);
map.animateCamera(cameraUpdate);
/*startLocationUpdates();*/
} else {
Toast.makeText(this, "Current location was null, enable GPS on your mobile!", Toast.LENGTH_SHORT).show();
}
}
private void initListeners() {
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
map.getUiSettings().setZoomControlsEnabled(true);
map.setMyLocationEnabled(true);
map.setOnMarkerClickListener(null);
map.setOnMapLongClickListener(null);
map.setOnInfoWindowClickListener(null);
map.setOnMapClickListener(null);
map.setTrafficEnabled(true);
map.setOnMapLongClickListener(this);
map.setOnMapClickListener(this);
map.setPadding(0, 80, 0, 0);
}
答案 0 :(得分:8)
问题是,当您恢复时,mMap
为空,然后您无法使用mMap.moveCamera();
,这会导致您的应用崩溃。
解决方案是在尝试再次使用之前检查是否需要设置地图。
我稍微修改了你的代码,以检查是否需要在onCreate和onResume中设置地图。请注意,我使用的是onPause而不是onStop,因为它与onResume相对应。
private GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setupMapIfNeeded();
}
private void setupMapIfNeeded() {
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if (mMap == null) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
MapStateManager mgr = new MapStateManager(this);
CameraPosition position = mgr.getSavedCameraPosition();
if (position != null) {
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
Toast.makeText(this, "entering Resume State", Toast.LENGTH_SHORT).show();
mMap.moveCamera(update);
mMap.setMapType(mgr.getSavedMapType());
}
}
@Override
protected void onPause() {
super.onPause();
MapStateManager mgr = new MapStateManager(this);
mgr.saveMapState(mMap);
Toast.makeText(this, "Map State has been save?", Toast.LENGTH_SHORT).show();
}
@Override
protected void onResume() {
super.onResume();
setupMapIfNeeded();
}
MapstateManager完全相同。
public class MapStateManager {
private static final String LONGITUDE = "longitude";
private static final String LATITUDE = "latitude";
private static final String ZOOM = "zoom";
private static final String BEARING = "bearing";
private static final String TILT = "tilt";
private static final String MAPTYPE = "MAPTYPE";
private static final String PREFS_NAME ="mapCameraState";
private SharedPreferences mapStatePrefs;
public MapStateManager(Context context) {
mapStatePrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
public void saveMapState(GoogleMap mapMie) {
SharedPreferences.Editor editor = mapStatePrefs.edit();
CameraPosition position = mapMie.getCameraPosition();
editor.putFloat(LATITUDE, (float) position.target.latitude);
editor.putFloat(LONGITUDE, (float) position.target.longitude);
editor.putFloat(ZOOM, position.zoom);
editor.putFloat(TILT, position.tilt);
editor.putFloat(BEARING, position.bearing);
editor.putInt(MAPTYPE, mapMie.getMapType());
editor.commit();
}
public CameraPosition getSavedCameraPosition() {
double latitude = mapStatePrefs.getFloat(LATITUDE, 0);
if (latitude == 0) {
return null;
}
double longitude = mapStatePrefs.getFloat(LONGITUDE, 0);
LatLng target = new LatLng(latitude, longitude);
float zoom = mapStatePrefs.getFloat(ZOOM, 0);
float bearing = mapStatePrefs.getFloat(BEARING, 0);
float tilt = mapStatePrefs.getFloat(TILT, 0);
CameraPosition position = new CameraPosition(target, zoom, tilt, bearing);
return position;
}
public int getSavedMapType() {
return mapStatePrefs.getInt(MAPTYPE, GoogleMap.MAP_TYPE_NORMAL);
}
}
答案 1 :(得分:2)
如果您只想在方向更改之间保存和恢复相机位置,则可以将nginx
实例本身保存在saveInstanceState包中。 CameraPosition
实现了CameraPosition
,所以这应该有效。
ReflectedParcelable
要恢复,请执行以下操作
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (googleMap != null) {
outState.putParcelable(STATE_KEY_MAP_CAMERA, googleMap.getCameraPosition());
}
}
答案 2 :(得分:1)
mapFragment.setRetainInstance(true);
您可以在onCreate中使用它来保存地图片段状态