Android Question [SOLVED] What is best strategy for working geofences in Android 11?

Sandman

Expert
Licensed User
Longtime User
Geofences in earlier versions of Android work just fine, but in Android 11(*) it doesn't seem to work as-is.

So I made a marathon post where I did a lot of tests, trying to figure out things:

It seems the root problem is that the OS kill the app to save battery. In itself this shouldn't be a problem at all, as long as the OS launch the app when it detects a geofence event.

The problem is that the OS doesn't do this. This seems super strange to me, and I have a very strong feeling of me missing something important. In the meantime, I found two workarounds of keeping the app alive, none of them are groundbreaking for forum members. None of these seem optimal, and I want to repeat that I suspect none of these are the intended solutions for working geofences in Android 11. It's just the best I've been able to figure out:


1. Create a basic foreground service

Pros
  • Doesn't require any action by the user

Cons
  • Add to visual clutter in phone (while likely not adding much useful information)
  • Uncertain it actually helps keep the app alive in the long run? (opinions welcome!)

2a. Disable battery optimization, method 1: Asking user to do it manually

This method is just guiding the user to do it for us.

Pros
  • Guaranteed to work, if we can get the user to do it

Cons
  • Different versions of OS and phone model might require different ways for user to navigate the OS user interface - difficult to give simple instruction that applies to everybody?
  • Complicated instructions for the typical user. Example how other people have solved it: (source)
    • Click DISABLE in our custom popup (where we mention that disabling battery optimization will give them more consistent location tracking experience)
    • Select 'All Apps' from Battery Optimization Android Settings page
    • Search and select our app name
    • Select 'Don't Optimize'.

2b. Disable battery optimization, method 2: Using manifest and simple user action

This method consists of adding something to the manifest, and then use an intent that pretty much ask the user "should we disable battery optimization for this app?" with a simple Yes/No for the user. (Note: I haven't researched the details more than this, but I don't think I'm far away from how it's working.)

Pros
  • Guaranteed to work

Cons
  • Very dangerous, Google might ban app (source, source 2, source 3) if you can't give an acceptable use-case
    • No obvious way of communicating with Google about this, either before submitting app, before getting banned, or after getting banned


For what it's worth, I'm certain that I for my app do have a solid use-case for 2b. But I still don't have a reliable way of discussing things with Google so I am uncertain I dare to try that method.


Questions
  • Did I miss any pros or cons?

  • Are all of these methods roughly the same from a battery-usage perspective? Anyone better or worse?

  • What are your opinions on the best strategy?


(*) I don't know exactly what version of Android it became more problematic, perhaps 10?
 
Last edited:

roumei

Active Member
Licensed User
I'd prefer the foreground service. If a user really wants to use some kind of geofencing, they probably won't mind the small notification icon. Given the latest location permission changes, implementing background location tracking with the foreground service seems to me like the most future-proof variant. Another advantage is that you can use an unlimited number of complex polygons if you implement it yourself.
A couple of weeks ago I created a small 'geofencing' app (works only in foreground mode) to show a 15 km radius around city boundaries (Bewegungsradius Deutschland – Apps on Google Play, available in German only). It took me only 2 days to create the Android and the iOS version. With all the trouble you were experiencing with geofences I'm glad that I didn't try to implement it that way.
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
With all the trouble you were experiencing with geofences I'm glad that I didn't try to implement it that way.
I'm guessing you used the GPS for positioning instead, correct? And not used the built-in functionality for geofences?
 
Upvote 0

roumei

Active Member
Licensed User
Yes, just GPS and some point-in-polygon tests.
B4X:
Type ePoint(X As Int, Y As Int, Lat As Double, Lon As Double)

Sub IsPointInPolygon(polygon As List, X As Double, Y As Double) As Boolean
    Dim result As Boolean = False
    Dim j As Int = polygon.Size - 1
    For i = 0 To polygon.Size - 1
        Dim pi As ePoint = polygon.Get(i)
        Dim pj As ePoint = polygon.Get(j)
        If pi.Y < Y And pj.Y >= Y Or pj.Y < Y And pi.Y >= Y Then
            If pi.X + (Y - pi.Y) / (pj.Y - pi.Y) * (pj.X - pi.X) < X Then
                result = Not(result)
            End If
        End If
        j = i
    Next
    Return result
End Sub
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Yes, just GPS and some point-in-polygon tests
That's pretty much how my app currently work. It's fine from a feature perspective, but I do have users complaining about the excessive battery usage. As I understand it, geofences are supposed to be dramatically more power efficient. That's the reason for why I'm investigating this. (There are other reasons also, but that's the main one.)
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Please try the attached project. Make sure to change the center location.

It should work better in the background.
I've tried the project and can confirm that it works great, thanks!

I've also updated my overly long post, for completeness and posterity, with a test 10 and 11.

I'd recommend updating your post to include your new code:
 
Upvote 0
Top