2

This might help someone one day.

Background

Around Nov23rd2022 our team started receiving complaints from users, about our app that does attendance by ensuring that users can only work in designated locations.

we do this by comparing the current gps cordinates with those stored regarding intended work location.

Some users , mainly those having Go Edition phones could not get gps accuracy at all in the app and since it only allows work to start if gps accuracy is about 200m around the location, they could not work!

We had coded the app such that we use LocationManager and calling the GPS Hardware directly. ie

LocationManager locationManager = (LocationManager) Our_app.getAppContext().getSystemService(LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

In case Location data is not available via the GPS_PROVIDER we would switch to NetworkProvider by checking if its available

isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

The Challenge

Around 23rd Nov 2022 either Google or the phone manufacturer pushed out an update that forced their phones to use ONLY BATTERY SAVING MODE without any option to update to High Accuracy. Due to this both GPS_Provider and Network_Provider were returning NULL! no locations at all. and due to this any user with Go Edition Tecno phone couldnt work.

Troubleshooting

We decide to unComment and test some very old GPS Service code, we had written but commented out since 2017 since our tests showed that the Location accuracy of GoogleApiClient FusedLocation service was not enough for us to use in the app and therefore had put it aside and focused on hardware gps which was super.

after enabling the old code, suprisingly it would not work.

 using LocationServices.FusedLocationApi.requestLocationUpdates,    
    OnLocationChanged somehow was NEVER CALLED!  

So after much research we Updated to the latest

mFusedLocationClient = LocationServices.getFusedLocationProviderClient(our_app.getAppContext());

However on starting the Service with foreground notification (in Oreo and Later), Only 1 location Update would be returned! onLocationResult would not get continous updates even though we specified RealTime mode

ie  mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(0);
    mLocationRequest.setFastestInterval(0);
    mLocationRequest.setSmallestDisplacement(0);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

Still nothing!

After more research realized because we were targeting minSdkVersion 16 and targetSdkVersion 31 we had to use a PeriodicWorker to run in the background say every second and listen for onLocationResult then broadcast the cordinates so the rest of the app knew the latest Long and Latt.

This Finally worked! Phew. The other challenge was ofcourse knowing when to stop RealTime updates so as not to drain battery. to solve this we simply compared the LastKnownLocation Accuracy withi the Current accuracy. if current accuracy was less than or equal to our intMinAccepted Accuracy we killed the worker and restarted with longer gps interval and displacement.

In Summary

If you suddenly find that your users cant get accurate location and they are on Android GO devices, just switch to a Periodworker and put your LocationCode in the worker. This stackoverlow question (How can location updates from FusedLocationProviderClient be processed with Work Manager?) and this example within it ( https://github.com/pratikbutani/LocationTracker-WorkManager as link to github) helped us understand what to do. THANK YOU PRATIK BUTANI!

KuriaNdungu
  • 623
  • 8
  • 20

0 Answers0