This activity displays geofences to the map. They're added as objects to an arraylist and then used by initArea() and are shown on the map. My issue is initArea() runs before onDataChange() so nothing is added to the arraylist and a null pointer exception is thrown. I want onDatachange() to run first so that the arraylist is populated. Thanks in advance :)
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GeoQueryEventListener {
private static final String TAG = "Maps";
private GoogleMap mMap;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
private FusedLocationProviderClient fusedLocationProviderClient;
private Marker currentLocation;
private DatabaseReference locationRef;
private GeoFire geofire;
private List<LatLng> geoFence;
ArrayList<geofenceObj> geoTemp = new ArrayList<>();
private String userID;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private int check;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
}
};
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
showData(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
buildLocationRequest();
buildlocationcallback();
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MapsActivity.this);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
initArea();
settingGeofire();
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
Toast.makeText(MapsActivity.this, "Permissions not enabled ", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
}
}).check();
}
private void showData(DataSnapshot dataSnapshot) {
geoTemp.clear();
for(DataSnapshot i : dataSnapshot.getChildren()) {
for(int j=1; j<=dataSnapshot.child("users").child(userID).getChildrenCount(); j++) {
String ID = String.valueOf(j);
if (i.child(userID).child(ID).getValue() != null) {
geofenceObj geofence = new geofenceObj();
geofence.setName(Objects.requireNonNull(i.child(userID).child(ID).getValue(geofenceObj.class)).getName());
geofence.setRadius(Objects.requireNonNull(i.child(userID).child(ID).getValue(geofenceObj.class)).getRadius());
geofence.setLat(Objects.requireNonNull(i.child(userID).child(ID).getValue(geofenceObj.class)).getLat());
geofence.setLng(Objects.requireNonNull(i.child(userID).child(ID).getValue(geofenceObj.class)).getLng());
geoTemp.add(geofence);
Log.d(TAG, "Added " + geofence.getName());
}
}
}
}
private void initArea() {
geoFence = new ArrayList<>();
geoFence.add(new LatLng(0, 0));
for(int i = 0; i <= geoTemp.size(); i++){
geoFence.add(new LatLng(geoTemp.get(i).getLat(), geoTemp.get(i).getLat()));
}
Log.d(TAG, "Initialised Area");
}