Geolocation with GPS in Ionic

09/08/2022Por iCarto

When we talk about geolocation we refer to the ability of a device to obtain the geographical position in which it is located. To do this, you can use the WiFi access point to which you are connected, the mobile phone tower to which you are linked (in the case of phones or other mobile devices that have a SIM card) or through GPS technology. when you have it. Even these different options can be combined with each other to improve the precision that each of them offers us separately.

In mobile devices, this ability to obtain geolocation greatly opens up the range of applications that can be developed, some examples may be the creation of Apps to inventory information, including the geographical position of each element, store routes or get information about what we have nearby, etc. The possibilities are almost endless.

Recently, at iCarto, we had the need to develop a mobile application with which to collect information on the route followed to collect wild mushrooms. We are committed to developing this application using web technologies adapted to create mobile applications, specifically using the framework Ionic with ReactJS. In this project we had some particular need related to precision and the possibility of collecting route points even if the application was in the background and the device was being used for something else. That made us look at different geolocation plugins available for Ionic. In this article we want to share this analysis, as well as some of the conclusions and learnings along the way.

When working with technologies to develop a mobile application, by default we can use the W3C Geolocation API that browsers implement. However, the use of a specific geolocation plugin is recommended, which we can activate if we use Cordova to package the mobile application, or in our particular case Capacitor, the tool provided by Ionic. It is a good practice in general, since in this way we ensure that we will have the functionality available regardless of the version of the browser that the mobile device has. Let’s remember that when using this type of technology, in the end our application, on the mobile device, is running inside a web browser. But it is also that in our particular case it was mandatory, because we needed specific functionalities, which the geolocation API does not offer, such as support to continue obtaining the location when the application is in the background.

Cordova vs. Capacitor

Before going into the analysis of geolocation plugins, it is good to stop and review the two main alternatives for packaging mobile applications when we work with web technologies for their development.

Apache Cordova was one of the first mobile application development environments using web technologies, CSS, HTML, and JavaScript, instead of using platform-specific APIs. This has its advantages and disadvantages, which we are not going to talk about now, since it would take several posts. The Ionic project started out using Cordova as an application packaging tool as well, but more recently it came out with its own, Capacitor. On the project website they tell us the reason for this change and what advantages Capacitor brings.

One of the advantages of Capacitor is that it is fully compatible with Cordova, and therefore we can use plugins that are available for the latter even if they do not exist in Capacitor, or even if there is an equivalent version we can use the one from * Cordova* if we are interested for any reason. This, for example, allowed us to expand the range of plugins to review.

Precisely because Cordova has been available for much longer, the number of plugins that we can find, both official and developed by the community, is much greater today than in the case of Capacitor, which despite also having quite a few plugins developed by their community, in addition to official, due to their youth they are still less.

Geolocation plugins

Both Cordova and Capacitor have a default geolocation plugin, based on the browser API. They are easy-to-use plugins, which are available without having to add anything and that basically allow us to obtain the coordinates of the position in which the mobile device is located. Its API gives us two functions:

  • getCurrentPosition: Gives us the coordinates when we call it.
  • watchPosition: Allows us to connect to a watcher that returns the coordinates of the position every time there is a change, that is, every time we move.

In none of the cases can coordinates be obtained when the application is in background, one of the requirements that our application did have, for example, since when collecting a long route, it was necessary to be able to use the phone at the same time to other tasks, without stopping recording the route.

Luckily, thanks to the community we have more options available. In our case, we tried two other plugins that allow geolocation to work in background.

  • BackgroundGeolocation by Capacitor-community: It is the latest plugin with support for working with geolocation in background, specific to Capacitor and with support for TypeScript.
  • Cordova Plugin Background Geolocation: The classic plugin used in Cordova environments when background geolocation is needed. The last release is 3 years ago, although it still works fine on recent versions of Android.

Within the tests we did with these two plugins, in both we achieved sufficient precision for the needs of the project, in most cases of a few meters. The plugin options allow us to play with various parameters to optimize the needs of precision of the coordinates that are obtained with the battery life of the device, for example.

Although the plugin for Capacitor is more current, the reality, at least in our case, is that we had problems with more modern mobiles, from Android 10, however it seemed to work without problem in older versions. The Cordova plugin however behaved well from the start on both older and more modern mobiles. For this and other small details we ended up deciding on the latter for our project.

Some problems detected along the way

Once the plugin was selected and despite having done a fairly exhaustive analysis and various tests, during development we still had to solve some problems. The first of them has to do with the abstraction layers that some manufacturers introduce on Android to customize their devices. It is a fairly well-known topic and is well documented on the Internet. The problems are usually related to battery management, looking for battery savings, what some of these customizations do and what caused our background service to stop. On the Don’t kill my app! website, most of these cases are documented and how to configure the device to prevent battery saving management from canceling this type of process.

Another problem that we had that was not so easy to identify and solve has to do with Android version 10. What happened is that once the application was put in background, points continued to be collected, but after a certain time they stopped collecting, approximately 30 seconds. Upon retrieving the application and having the main focus on the system, then the collection of points continued as if nothing had happened. It was clear that this problem was not the same as the previous one, since the application did not die due to battery management. The real issue is related to the new permission management introduced in Android 10 that allows you to choose whether a permission is granted always or only when the app is in use. This second option is the one that causes problems, since only when the application is in use actually means when the application is visible on the screen, in the foreground, and not when it is running in the background.

Our solution was to explicitly add the andorid:foregroundServiceType=”location” option to the AndroidManifest.xml. In this way we indicate that our app is a location service and always needs access to GPS. The complete line in the AndroidManifest.xml would look like this:

< service android:enabled="true" android:exported="false" android:foregroundServiceType="location" android:name="com.marianhello.bgloc.service.LocationServiceImpl" />

You also need to explicitly grant ACCESS_BACKGROUND_LOCATION permission as detailed in the documentation.

Final considerations

When choosing a plugin, as well as any development software or library in general, the functionalities it offers us are as important as its evolution and maintenance. In our case, we bet on a plugin that has not been active in its repository for some time, this implies that it is not maintained and future improvements are not expected. On the other hand, the one that fit in these criteria did not offer us the functionality we needed. Perhaps it is an extreme case that we found and that is why we made that decision. In any case, our recommendation is to always take into account the activity of the repository of a solution, seeing that it is and will continue to be maintained over time, that there is a community around it and that it is a safe bet. When this is not possible, you have to consider other things to make the choice and even if it were possible, try to create your own solution.