I have a route tracking app that uses GoogleMaps
and Location Services
. And everything worked fine until yesterday that my app crash every time with a NullPointerException
and i don't know why, i haven't changed anything in the code.
Here's the code:
package com.example.rocketron.mapa.Activities;
import android.location.Location;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.rocketron.mapa.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.MapView;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends AppCompatActivity implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
protected static final String TAG = "location-updates-sample";
// Keys for storing activity state in the Bundle.
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
//UI Elements
protected Toolbar toolbar;
protected FloatingActionButton fab;
protected GoogleMap googleMap;
protected MapView mapView;
//Provides the entry point to Google Play services.
protected GoogleApiClient mGoogleApiClient;
//Stores parameters for requests to the FusedLocationProviderApi.
protected LocationRequest mLocationRequest;
//Represents a geographical location.
protected Location mCurrentLocation;
//Tracks the status of the location updates request. Value changes when the user presses the
//Start Updates and Stop Updates button.
protected boolean mRequestingLocationUpdates;
protected double latitude;
protected double longitude;
protected LatLng mLatLng;
protected CameraUpdate cameraUpdate;
Marker currentMarker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.appbar);
setSupportActionBar(toolbar);
fab = (FloatingActionButton) findViewById(R.id.fab);
mapView = (MapView) findViewById(R.id.mi_mapa);
mapView.getMapAsync(this);
mapView.onCreate(savedInstanceState);
mRequestingLocationUpdates = false;
updateValuesFromBundle(savedInstanceState);
buildGoogleApiClient();
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
togglePeriodicLocationUpdates();
}
});
}
@Override
public void onMapReady(GoogleMap map) {
googleMap = map;
googleMap.getUiSettings().setMapToolbarEnabled(false); //Hide Map Toolbar when marker is clicked
}
@Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
@Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
/**
* Updates fields based on data stored in the bundle.
*
* @param savedInstanceState The activity state saved in the Bundle.
*/
private void updateValuesFromBundle(Bundle savedInstanceState) {
Log.i(TAG, "Updating values from bundle");
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
// the Start Updates and Stop Updates buttons are correctly enabled or disabled.
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
REQUESTING_LOCATION_UPDATES_KEY);
setFabEnabledState();
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
// Since LOCATION_KEY was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
}
updateUI();
}
}
/*------------- Build Google API Client ----------------*/
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
/*------------- Set Up a Location Request -----------------*/
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void updateUI() {
if (currentMarker != null)
currentMarker.remove();
latitude = mCurrentLocation.getLatitude();
longitude = mCurrentLocation.getLongitude();
mLatLng = new LatLng(latitude, longitude);
cameraUpdate = CameraUpdateFactory.newLatLng(mLatLng);
googleMap.moveCamera(cameraUpdate);
currentMarker = googleMap.addMarker(new MarkerOptions()
.position(mLatLng)
.title(String.format("%f, %f", latitude, longitude))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
}
private void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) {
// Changing the fab button
mRequestingLocationUpdates = true;
setFabEnabledState();
getSupportActionBar().hide();
// Starting the location updates
startLocationUpdates();
} else {
// Changing the fab button
mRequestingLocationUpdates = false;
setFabEnabledState();
getSupportActionBar().show();
// Stopping the location updates
stopLocationUpdates();
}
}
private void setFabEnabledState() {
if (mRequestingLocationUpdates) {
fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_stop_white_24dp));
} else {
fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_play_arrow_white_24dp));
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/*-------------Override Methods from ConnectionCallbacks, OnConnectionFailedListener-------------*/
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
updateUI();
}
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
@Override
public void onConnectionSuspended(int i) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
/*----------------Override Methods from LocationListener ----------------------*/
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
updateUI();
Toast.makeText(this, getResources().getString(R.string.location_updated_message), Toast.LENGTH_SHORT).show();
}
/*------------------Stores activity data in the Bundle.--------------------*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, mRequestingLocationUpdates);
savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
super.onSaveInstanceState(savedInstanceState);
}
/*----------------Toolbar Methods---------------*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And the error:
02-15 07:02:47.675 13898-13898/com.example.rocketron.mapa
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.rocketron.mapa.Activities.MainActivity.updateUI(MainActivity.java:187)
at com.example.rocketron.mapa.Activities.MainActivity.onConnected(MainActivity.java:244)
at com.google.android.gms.common.internal.zzk.zzk(Unknown Source)
at com.google.android.gms.internal.zzmg.zzi(Unknown Source)
at com.google.android.gms.internal.zzme.zzpi(Unknown Source)
at com.google.android.gms.internal.zzme.onConnected(Unknown Source)
at com.google.android.gms.internal.zzmi.onConnected(Unknown Source)
at com.google.android.gms.internal.zzlz.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzg.zzqv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzc.zzqx(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)