React Native — Background Location Tracking without Timeout and with App killed

Sourab Kumar
ITNEXT
Published in
4 min readJan 30, 2021

--

Edit (10th Feb 2024):

It’s been ages since I wrote this blog, it’s still garnering views and people are reaching out.
I will be writing a follow up blog on a product I have built, which enables users to share their live location (just like WhatsApp) for both Android and iOS and as well as stream it to your own personal web servers using a web-hook.

If you’re interested in getting an early paid access to it, please fill the below form, i will get in touch with you over email.

Early Access: https://forms.gle/biz77SiTaMhWGFRZ9

Little Background:
I had built a Native Android app in Java a couple of months back where the requirement was to track the user’s location even when the app is closed, killed, in the background or foreground. This was easily possible before Android 8 (API level 26), where there was no restriction in fetching the user’s location in the background without their knowledge.
Since Android 8 things changed for developers and Android users. Now, the apps background services which tracked user’s location were killed forcefully if they were making too many GPS requests or if they were draining the battery in the background. Here enters Battery Optimisation feature of android.

At this point in time, I had onePlus 7T which was an Android 10 device and until I disabled the Battery Optimisation from the settings of that app, it wouldn’t let the app track the user. I had used a JobScheduler which ran every 10 seconds to get the GPS location from the device. I had an option to use ForegroundService, but the issue with that was persistent notification which user couldn’t close or swipe. Like the one in Aarogya Setu App. (And disabling the battery optimisation was good enough for the MVP)

I was asked to build the same app in React-Native for both Android and iOS.

And the last couple of days, I struggled to access geolocation from the device here was some of the problems I faced and how I came up with the solution (specifically for Android).

  1. Keep a service running when the app is killed — without disabling battery optimisation
  2. Access the device GPS every 10 seconds even when the app is killed— The React-Native Geolocation Library kept timing out after every 30–45 seconds after the app was killed. The library lost access to the GPS after a certain point of time.
  3. When I had a continuous looping foreground service running which accessed the GPS location in every 10 seconds — this didn’t let the app close or kill the app. It affected the React component life cycle.

1. Keep a service running when the app is killed — without disabling battery optimisation

I had learnt from my mistake the first time, there wasn’t a straight-forward (legal) way to keep a background service running without the user’s knowledge. So I had to use ForegroundServices to keep the process running, which also kept the user informed why this service was running even after they killed the app.
I used @supersami/rn-foreground-service library for this.
Here’s a blog on how you can create an everlasting service which can do background task using the above library. (Link to the blog)

3. When I had a continuous looping foreground service running which accessed the GPS location in every 10 seconds — this didn’t let the app close or kill the app. It affected the React component life cycle.

If you read the above blog of the library, it asks you to initialise the ForegroundService or the background task outside the life cycle of the react component. But when I was using @react-native-community/geolocation and react-native-geolocation-service to access the GPS location inside that background service, it used to only get initialised when the lifecycle of the react component started, hence making the background service enter the lifecycle of the component. And each time, the service looped the components used to re-render and you can imagine now why I was not able to close the app because I had my service to loop every 10 seconds.
So I tried this another library react-native-location which worked flawlessly with the background task.

2. Access the device GPS every 10 seconds even when the app is killed without request TIME-OUT

All the above things won’t work with Android 10 or above device, even if you implement them correctly. Because, since Android 10, the developers are supposed to ask another permission called ACCESS_BACKGROUND_LOCATION to access the location of the device and if the user denies the permission, you can’t invoke this permission request again and again. Android won’t allow you. So you have got one shot, so make it worthwhile with good reason so that the user understands the importance of the permission.
This was the reason why the time-out was happening. I had not asked for the user’s permission and yet I was requesting the GPS location.

Code:

Permission Request to Access Background Location
Foreground Service with Location Tracking

Result:

This was when the app was killed and the location update kept coming for next 2–3 hours.

Thank you for reading this, I hope this helped you. I documented this because I barely found any solution with proper reasoning anywhere. Took almost 2 days of soul searching and some of my native android development experience to connect the dots for React-Native.

I have actually documented my React-Native learning journey and what kind of problems I faced and where I have found my solution and what I understood from them. This blog is just one example of a specific problem. Do let me know if you liked this format of the blog so that I can write more.

You can reach me on Twitter: https://twitter.com/sourav_bz

--

--