I am trying to test Geofence functionality using Google's example: Creating & Monitoring Geofences. I have uploaded the code here.
Problem is that I never get a notification of entry or exit. I have Wifi, 4G and GPS on. I have tried to test in the following ways:
I even walk out of my house for about 50ft and walk back in - but no notifications. I can see that play services gets connected and even the "GeofenceUtils.ACTION_GEOFENCES_ADDED in MainActivity.java" gets triggered, so I think Geofences are getting added correctly.
Enabled Mock Locations in the Settings and used this Fake GPS App and changed location - starting from the same coordinates as the Geofence1 and then setting to something totally outside (in another state) - but I still dont get an exit notification.
What am I doing wrong? ANyone had success in running this Google's example: Creating & Monitoring Geofences. I have uploaded the code here for easy browsing.
I am just trying to learn Geofencing - detecting entry & exit. I WILL MARK ANY ANSWER AS THE RIGHT ANSWER THAT I CAN USE TO GET GEOFENCING WORKING ON MY REAL DEVICE
.
I was also having issues with the example code. One of the main issues I had was around declaring the ReceiveTransitionsIntentService. You don't need to add a BroadcastReceiver or request location updates, but you need to change your AndroidManifest to set the exported value to true, like so:
<service
android:name=".ReceiveTransitionsIntentService"
android:exported="true" >
</service>
Make sure that the path to the service is also correct.
I've simplified the Google example significantly and you can find the code and explanation here. I've removed the UI component and persistent Geofence storage, so this example should be easier to follow. Hope this helps!
Initally my code was running smoothy but after that I too get this problem , Please try this by modifying geofenceRequester class in continueAddGeofences() function.
basically it is calling the receiver through location request method
private void continueAddGeofences() {
// Get a PendingIntent that Location Services issues when a geofence
// transition occurs
mGeofencePendingIntent = createRequestPendingIntent();
// Send a request to add the current geofences
mLocationClient.addGeofences(mCurrentGeofences, mGeofencePendingIntent,
this);
//mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
try {
LocationRequest locationrequest = LocationRequest.create();
locationrequest.setPriority(locationrequest.PRIORITY_HIGH_ACCURACY);
locationrequest.setInterval(3000);
mLocationClient.requestLocationUpdates(locationrequest, mGeofencePendingIntent);
} catch (Exception e) {
e.printStackTrace();
}
I was also having the same problem with Geofence api. At the end, I used addProximityAlert of LocationManager.It did work very well!
Related
I would like to ask a clarification about the meaning of the "Searching gps" notification. I have a simple app that tries to retrieve user position via FusedLocationProviderClient with this code:
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity as Activity)
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
mMap.isMyLocationEnabled = true
// other trivial stuff here
}.addOnFailureListener {
// showing an error here
}
Even when last location is retrieved android keeps showing the "Searching gps" notification (Ricerca gps in the screenshot below). As far as you know, this means that app is still searching for gps updates (and so draining battery) or is a simple message to notify the user that the app is using the gps? Thanks for the clarification, my device is a Xiaomi Redmi 5 Plus (MiUI)
I'm not 100% sure I understand the question, but I'll take a stab here. I think one of two things is going on:
The notification is being explicitly shown by the MyFoody app and it's that app's responsibility to hide the notification once it no longer needs to be shown. You'd need to take care of clearing that notification in the listener's success and failure functions you've defined. Are your listeners being called? Do they clear the notification?
OR
It may be that Xiaomi has modified Android to show that notification on behalf of your app while it's retrieving location(s). If that's the case, then you'd need to figure out why this Xiaomi-modified Android version still thinks your app is trying to get a location. It could also just be a bug on Xiaomi's part, but I'd consider that as a last resort.
In my app I am using FusedLocationProviderClient to get user location every time he enters the app by mFusedLocationClient.getLastLocation().addOnCompleteListener().But sometimes result is null,I am using <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> in manifest.How can I get user location even if it not so correct?Because the logic of app depends on that location,I don't need to show it on map or smth like that,just get the location.Thx in advance
Don't use getLastLocation(). There is always a chance to have it return null if it doesn't have a location currently.. Use requestUpdates or requestSingleUpdates- when the callback for those is called the location is guaranteed to be non-null. getLastLocation() should only be used as an optimization to improve speed, it cannot be relied on.
Follow the following example and your app is guaranteed to work as you wish. I have recently used this code and it is working like a charm.
Only thing you should know is that for the location updates to actually work ( to get real latitude and longitude values) you should enable "google play services". There may be several ways to do this but perhaps the simplest of all is to open "settings" on your device and probably somewhere under "security" or "permissions" (depending on your android distribution) find "google play services" and give it the permission it needs.
https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates
SO I've created geofence as below:
GeofenceModel modelExit = new GeofenceModel.Builder("id_oi_456")
.setTransition(Geofence.GEOFENCE_TRANSITION_DWELL)
.setExpiration(Geofence.NEVER_EXPIRE)
.setLatitude(40.414341)
.setLongitude(49.928548)
.setRadius(CLIENT_GEOFENCE_RADIUS)
.build();
SmartLocation.with(this).geofencing()
.add(modelExit)
.start(this);
I run this code once, it triggers when dwelling inside geofence (as expected). And then I delete the snippet and rerun the project. But geofence not triggered this time even if I have set NEVER_EXPIRE. So basically what I want to know is that where are the geonfences stored. In case they are stored outside app memory then why "deleting snippet" clears geofence?
I think it is working as intended. The project that goes to re-run will consider the app as fresh install. As stated in the documentation - Use Best Practices for Geofencing:
The app must re-register geofences if they're still needed after the following events, since the system cannot recover the geofences in the following cases:
The device is rebooted. The app should listen for the device's boot complete action, and then re- register the geofences required.
The app is uninstalled and re-installed.
The app's data is cleared.
Google Play services data is cleared.
The app has received a GEOFENCE_NOT_AVAILABLE alert. This typically happens after NLP (Android's Network Location Provider) is disabled.
Hope this helps.
I'm working with geofences on android, it's all working fine on most phones,
but on some of them, it's just not working (showing "geofences not available" in my error logs).
Some users don't have their location tracking enabled for Google Play Services.
I think that is the reason why geofencing is not working on their phones. (right?)
Now I want a way to detect this. (inform the user and eventually show them how to fix it)
I know there is a way to know wether google play services is available or not (and I already do this), but that doesn't say anything about the location services being enabled or not.
I know that I can check it while adding or removing geofence, there is an error code for it (geofence not available Location Status Codes), but that's not enough.
Some users disable the location services after they added the geofences. Then I have no way of knowing this, and my app won't work. (complaining users etc.).
At least I have to inform the user when they open the app to check what's wrong.
Does someone have an idea on how to do this?
The best I can do now is adding and removing a dummy geofence on app boot, but there has to be a better way?
EDIT:
I tested it with a device that had the issue, removing the app and reinstalling seems to fix the problem.
I'm not doing anything special on the first boot, so this is really weird.
It looks as if there is a problem with the google play services connection, and reinstalling the app does something special with these services.
Is this possible? It gives no errors while connecting to them, but it did when I tried to set geofences (see above).
The geofences will get disabled (and unregistered) if the GPS Provider or the Network Provider are disabled for whatever reason. That will cause your onAddGeofencesResult() to get called with an status code of error (1000). You can detect it right there.
Or, you detect this by implementing a Receiver that gets called in response to android.location.PROVIDERS_CHANGED. Remember to add the receiver to the AndroidManifest
<receiver android:name=".service.GeofenceProvidersChangedBroadcastReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED"/>
</intent-filter>
</receiver>
On the receiver implementation, on its onReceive(), get the location manager and test for the providers status:
public class ProvidersChangedBroadcastReceiver extends WakefulBroadcastReceiver {
:
:
#Override
public void onReceive(Context context, Intent intent) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// GPS_PROVIDER IS enabled...
} else {
// GPS_PROVIDER is NOT enabled...
}
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
// NETWORK_PROVIDER IS enabled...
} else {
// NETWORK_PROVIDER is NOT enabled...
}
:
:
:
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
// We are good for geofencing as both GPS and Network providers are enabled....
}
:
:
:
}
I downloaded the GeoDetection.zip file for trying out location based geofencing using the Google Play Services API that is available from the developer android website from the following link:
http://developer.android.com/training/location/geofencing.html
but when i tried to add geo fences using this app, i constantly get the error GEOFENCE_NOT_AVAILABLE
i tried to check what this error means, and i found that if location access is not available that is when i should get this message, but i checked the Location Services section on my phone and i saw that all the Location provides GPS/Wifi Location are all enabled. I am also connected to WIFI successfully. Not sure why i still get the message.
Any body else encounter this issue?..if so, do you have a fix that i could try?
Any other suggestions?.. i tried a lot of options to make sure it is capturing all the options, but there is isn't much debug information for me to proceed any further.
Thanks in advance
Are you requesting the FINE_LOCATION permission?
Remember on Android 6 and above you have to handle the permissions at run-time too.
The above error, GEOFENCE_NOT_AVAILABLE is an expected error code, to let you know that the location adapter is off and location (and geofence) will NOT be tracked anymore.
Once available again, your geofences will be active and you will get the desired callback.
Few Reasons why the triggers aren't happening :
Check if your expiry timestamp that you set in your geofence request, is still valid.
Did your device get restarted ? If yes, you need to re-register fences. (Refer documentation : Re-register geofences only when required documentation)
Is your location, set to High Accuracy mode in Device settings ?
When you re-register your fences, you should un-register them first and then only re-register.
Open Google maps and check if it's showing the right location.
Is Battery Optimisation on for your device ? This will delay geofence triggers
Is you app whitelisted for background operations (Happens in some Chinese OEM's)