Reputation: 115
I used this code before but now i got some errors in Resuming the Map State. I got this code from David Gassner from its tutorial and now i want to use it again. im a little Bit Confused, I put some tossed message in order to trace. the LogCat report point the error in RESUME starting this line Anybody knows how to fix this?
map.animateCamera(update);
map.setMapType(mgr.getSavedMapType())
heres the Code:
@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);
}
}
Here is the error from the logcat. I only included the red lines.
> 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, Below is the modified mode but still not working can you take a look?
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);
}
Upvotes: 8
Views: 11209
Reputation: 411
If you want to just save and restore the camera position between orientation changes, you could just save the CameraPosition
instance itself on your saveInstanceState Bundle. CameraPosition
implements ReflectedParcelable
so this should work.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (googleMap != null) {
outState.putParcelable(STATE_KEY_MAP_CAMERA, googleMap.getCameraPosition());
}
}
And to restored it do the following
if (savedInstanceState != null) {
CameraUpdate cameraPos = CameraUpdateFactory.newCameraPosition(
(CameraPosition)(savedInstanceState.getParcelable(STATE_KEY_MAP_CAMERA)));
googleMap.moveCamera(cameraPos);
}
Upvotes: 3
Reputation: 37
mapFragment.setRetainInstance(true);
You can use it at onCreate to save map fragment state
Upvotes: 2
Reputation: 43314
The problem is that your mMap
is null when you are resuming, and then you cannot use mMap.moveCamera();
for example, which leads to your app crashing.
Solution for this is to check if the map needs to be set up before trying to use it again.
I slightly modified your code to check if the map needs to be set up in both onCreate and onResume. Note that I use onPause instead of onStop because it is the counterpart to 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 is exactly the same.
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);
}
}
Upvotes: 12