问题
In this app first i fetch current user data from firebase then get alluser data except current user data then i fetch real time current location and then update location of current user when user start geofense then it craete geofense as many as allotheruser except current user(if there is 5 other user except current user then i create geofense 5 times, give user uid as geofense id, and for geofense center i gave current user current location same center for all 5 geofense),
when this app is run and marker enter in geofense or exit from geofense it give meaningless result.
meaningless result means if otheruser marker didn't enter in geofense it give entring if user entering in geofense then it give enter some time some time don't as well as if otheruser marker exit from geofense then it give enter not exit
i want notification when allotheruser marker enter or exit from geofense
map acitivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
volumeControl = (SeekBar) findViewById(R.id.verticalseekbar);
volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
map.animateCamera(CameraUpdateFactory.zoomTo(progress),2000,null);
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
textLat = (TextView) findViewById(R.id.lat);
textLong = (TextView) findViewById(R.id.lon);
mAuth = FirebaseAuth.getInstance();
mTopToolbar = findViewById(R.id.my_toolbar);
setActionBar(mTopToolbar);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
getdata();
createGoogleApi();
//startGeofence();
}
@Override
protected void onStart() {
super.onStart();
// Call GoogleApiClient connection when starting the Activity
googleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
// Disconnect GoogleApiClient when stopping Activity
googleApiClient.disconnect();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.option_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.main_logout_option) {
mAuth.signOut();
LoginManager.getInstance().logOut();
gotologinactivity();
}
if (item.getItemId() == R.id.clear) {
clearGeofence();
return true;
}
if (item.getItemId() == R.id.add) {
startGeofence();
return true;
}
return true;
}
private void createGoogleApi()
{
Log.d(TAG, "createGoogleApi()");
if ( googleApiClient == null ) {
googleApiClient = new GoogleApiClient.Builder( this )
.addConnectionCallbacks(this)
.addOnConnectionFailedListener( this )
.addApi( LocationServices.API )
.build();
}
}
// Check for permission to access Location
private boolean checkPermission() {
Log.d(TAG, "checkPermission()");
// Ask for permission if it wasn't granted yet
return (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED );
}
// Asks for permission
private void askPermission() {
Log.d(TAG, "askPermission()");
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
REQ_PERMISSION
);
}
// Verify user's response of the permission requested
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()");
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch ( requestCode ) {
case REQ_PERMISSION: {
if ( grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED ){
// Permission granted
getLastKnownLocation();
} else {
// Permission denied
permissionsDenied();
}
break;
}
}
}
// App cannot work without the permissions
private void permissionsDenied() {
Log.w(TAG, "permissionsDenied()");
// TODO close app and warn user
}
@Override
public void onMapReady(GoogleMap googleMap)
{
map = googleMap;
}
@Override
public boolean onMarkerClick(final Marker marker)
{
return false;
}
// Start location Updates
private void startLocationUpdates(){
Log.i(TAG, "startLocationUpdates()");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
//movement in meter
if ( checkPermission() )
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged ["+location+"]");
lastLocation = location;
/*removeGeofenceDraw();
recoverGeofenceMarker();*/
clearGeofence();
startGeofence();
writeActualLocation(location);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.i(TAG, "onConnected()");
getLastKnownLocation();
recoverGeofenceMarker();
}
// GoogleApiClient.ConnectionCallbacks suspended
@Override
public void onConnectionSuspended(int i) {
Log.w(TAG, "onConnectionSuspended()");
}
// GoogleApiClient.OnConnectionFailedListener fail
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.w(TAG, "onConnectionFailed()");
}
// Get last known location
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation()");
if ( checkPermission() ) {
lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if ( lastLocation != null ) {
Log.i(TAG, "LasKnown location. " +
"Long: " + lastLocation.getLongitude() +
" | Lat: " + lastLocation.getLatitude());
writeLastLocation();
startLocationUpdates();
} else {
Log.w(TAG, "No location retrieved yet");
startLocationUpdates();
}
}
else askPermission();
}
private void writeActualLocation(Location location) {
textLat.setText( "Lat: " + location.getLatitude() );
textLong.setText( "Long: " + location.getLongitude() );
geoloc = (location.getLatitude() + 90) * 180 + location.getLongitude();
markerLocation(new LatLng(location.getLatitude(), location.getLongitude()));
markerForGeofence(new LatLng(location.getLatitude(), location.getLongitude()));
HashMap<String, Object> profileMap = new HashMap<>();
profileMap.put("latitude",location.getLatitude());
profileMap.put("longtitude", location.getLongitude());
profileMap.put("geoFireLocation", geoloc);
idd = mAuth.getCurrentUser().getUid();
db.collection("users").document(idd)
.update(profileMap)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid)
{
Log.d(TAG,"save");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG,"not save");
}
});
}
private void writeLastLocation() {
writeActualLocation(lastLocation);
}
private Marker locationMarker;
private void markerLocation(LatLng latLng) {
Log.i(TAG, "markerLocation("+latLng+")");
String title = latLng.latitude + ", " + latLng.longitude;
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.title(title);
if ( map!=null ) {
if ( locationMarker != null )
locationMarker.remove();
locationMarker = map.addMarker(markerOptions);
float zoom = 14f;
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, zoom);
//map.animateCamera(cameraUpdate);
}
}
private void markerForGeofence(LatLng latLng) {
Log.i(TAG, "markerForGeofence("+latLng+")");
String title = latLng.latitude + ", " + latLng.longitude;
// Define marker options
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
.title(title);
Log.e("marker",name+""+latLng.toString());
if ( map!=null ) {
// Remove last geoFenceMarker
if (geoFenceMarker != null)
geoFenceMarker.remove();
geoFenceMarker = map.addMarker(markerOptions);
Log.e("geomarker",title+""+geoFenceMarker);
}
}
private void startGeofence() {
Log.i(TAG, "startGeofence()");
if( geoFenceMarker != null ) {
for (int i=0;i<j;i++) {
Geofence geofence = createGeofence(geoFenceMarker.getPosition(), GEOFENCE_RADIUS, ids.get(i));
GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
addGeofence(geofenceRequest);
}
} else {
Log.e(TAG, "Geofence marker is null");
}
}
private Geofence createGeofence( LatLng latLng, float radius,String id) {
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(id)
.setCircularRegion( latLng.latitude,latLng.longitude, radius)
.setTransitionTypes( Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_EXIT )
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setNotificationResponsiveness(1000)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest( Geofence geofence ) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger( GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT )
.addGeofence( geofence )
.build();
}
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
if ( geoFencePendingIntent != null )
return geoFencePendingIntent;
Intent intent = new Intent( this, GeofenseTrasitionService.class);
return PendingIntent.getService(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT );
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.d(TAG, "addGeofence");
GeofencingClient mGeofencingClient = new GeofencingClient(getApplicationContext());
if (checkPermission())
mGeofencingClient.addGeofences(request, createGeofencePendingIntent())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
saveGeofence();
drawGeofence();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("failed","g");
}
});
/*LocationServices.GeofencingApi.addGeofences(
googleApiClient,
request,
createGeofencePendingIntent()
).setResultCallback(this);*/
}
@Override
public void onResult(@NonNull Status status) {
Log.i(TAG, "onResult: " + status);
if ( status.isSuccess() ) {
saveGeofence();
drawGeofence();
} else {
// inform about fail
}
}
private Circle geoFenceLimits;
private void drawGeofence() {
Log.e("circle", "draw");
if ( circle2 != null )
circle2.remove();
//LatLng last = new LatLng(22.28,73.1919983);
circle2 = map.addCircle(new CircleOptions()
.center(geoFenceMarker.getPosition())
.radius(GEOFENCE_RADIUS)
.strokeColor(Color.argb(50, 70,70,70))
.fillColor(Color.argb(100, 150,150,150))
.strokeWidth(5.0f));
// map.moveCamera(CameraUpdateFactory.newLatLng(geoFenceMarker.getPosition()));
}
// Saving GeoFence marker with prefs mng
private void saveGeofence() {
Log.d(TAG, "saveGeofence()");
SharedPreferences sharedPref = getPreferences( Context.MODE_PRIVATE );
SharedPreferences.Editor editor = sharedPref.edit();
editor.putLong( KEY_GEOFENCE_LAT, Double.doubleToRawLongBits( geoFenceMarker.getPosition().latitude ));
editor.putLong( KEY_GEOFENCE_LON, Double.doubleToRawLongBits( geoFenceMarker.getPosition().longitude ));
editor.apply();
}
// Recovering last Geofence marker
private void recoverGeofenceMarker() {
Log.d(TAG, "recoverGeofenceMarker");
SharedPreferences sharedPref = getPreferences( Context.MODE_PRIVATE );
if ( sharedPref.contains( KEY_GEOFENCE_LAT ) && sharedPref.contains( KEY_GEOFENCE_LON )) {
double lat = Double.longBitsToDouble( sharedPref.getLong( KEY_GEOFENCE_LAT, -1 ));
double lon = Double.longBitsToDouble( sharedPref.getLong( KEY_GEOFENCE_LON, -1 ));
LatLng latLng = new LatLng( lat, lon );
markerForGeofence(latLng);
drawGeofence();
}
}
// Clear Geofence
private void clearGeofence() {
Log.d(TAG, "clearGeofence()");
LocationServices.GeofencingApi.removeGeofences(
googleApiClient,
createGeofencePendingIntent()
).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if ( status.isSuccess() ) {
// remove drawing
removeGeofenceDraw();
}
}
});
}
private void removeGeofenceDraw() {
Log.d(TAG, "removeGeofenceDraw()");
if ( geoFenceMarker != null)
geoFenceMarker.remove();
if ( circle2 != null )
circle2.remove();
}
private void getdata() {
currentuserid = FirebaseAuth.getInstance().getCurrentUser().getUid();
db.collection("users").document(currentuserid).addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
if(documentSnapshot.exists())
{
current_name = documentSnapshot.getString("name");
current_lat = documentSnapshot.getDouble("latitude");
Log.e("lat",current_lat.toString());
current_long = documentSnapshot.getDouble("longtitude");
Log.e("lat",current_long.toString());
location = new LatLng(current_lat, current_long);
if(circle != null){
circle.remove();
}
try {
circle = map.addCircle(new CircleOptions()
.center(location)
.radius(3000)
.strokeColor(Color.BLUE)
.fillColor(0x220000FF)
.strokeWidth(5.0f)
);
}
catch (Exception e1)
{
Log.e("ex",e1.getMessage());
}
// map.addMarker(new MarkerOptions().position(location).title(current_name));
// map.moveCamera(CameraUpdateFactory.newLatLng(location));
Log.d(TAG,"data"+current_lat+" "+current_long+" "+current_name);
getalluser();
}
}
});
}
private void getalluser()
{
QueryLocation queryLocation = QueryLocation.fromDegrees(current_lat, current_long);
Distance searchDistance = new Distance(3, DistanceUnit.KILOMETERS);
geoFire.query()
.whereNearTo(queryLocation, searchDistance)
.build()
.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
if(mark!= null)
{
mark.remove();
}
j=0;
for(final QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots)
{
user = documentSnapshot.toObject(User.class);
current_names = user.getName();
LatLng all = new LatLng(user.getLatitude(),user.getLongtitude());
showmark(all,current_names,documentSnapshot.getId());
}
}
});
}
private void showmark(LatLng all, String current_n,String id)
{
if(!id.equals(currentuserid))
{
j++;
ids.add(id);
Log.d(TAG, "location"+" "+id+" "+currentuserid+" "+ all + " " + current_n);
vnrPoint = BitmapDescriptorFactory.fromResource(R.drawable.marker_a);
mark = map.addMarker(new MarkerOptions().position(all).icon(vnrPoint).title(current_n).snippet(id));
//startGeofence(id);
// map.moveCamera(CameraUpdateFactory.newLatLng(all));
//getnotification();
}
}
private void gotologinactivity() {
Intent intent = new Intent(MapsActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}
service
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// Handling errors
if ( geofencingEvent.hasError() ) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
Log.e( TAG, errorMsg );
return;
}
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
// Check if the transition type is of interest
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ) {
// Get the geofence that were triggered
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
// Send notification details as a String
sendNotification(geofenceTransitionDetails);
}
}
private String getdata(String g)
{
Log.e("f",g);
db.collection("users").document(g).addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
if(documentSnapshot.exists()) {
s_name = documentSnapshot.getString("name");
s_latitude = documentSnapshot.getDouble("latitude");
s_longtitude = documentSnapshot.getDouble("longtitude");
}
}
});
//Log.e("name",s_name);
return s_name;
}
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for ( Geofence geofence : triggeringGeofences ) {
String i = getdata(geofence.getRequestId());
Log.d(TAG,"id"+geofence.getRequestId());
triggeringGeofencesList.add(i);
}
String status = null;
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER )
status = "Entering ";
else if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
status = "Exiting ";
Log.e("notification",status+" "+triggeringGeofencesList);
return status + TextUtils.join( ", ", triggeringGeofencesList);
}
private void sendNotification( String msg ) {
Log.i(TAG, "sendNotification: " + msg );
// Intent to start the main Activity
Intent notificationIntent = MapsActivity.makeNotificationIntent(
getApplicationContext(), msg
);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MapsActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder
.setSmallIcon(R.drawable.ic_action_location)
.setColor(Color.RED)
.setContentTitle(msg)
.setContentText("Geofence Notification!")
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
it won't give any error but there is a bug so please give some suggestion
来源:https://stackoverflow.com/questions/57252645/some-bug-is-appear-while-check-user-are-enter-or-exit-from-geofense