See the App Inventor Extensions document about how to use an App Inventor Extension.
For questions about this extension or bug reports please start a new thread in the App Inventor community. Thank you.
For feature requests please contact me by email. To be a sponsor of a new method already is possible starting from only 10 USD! With your contribution you will help the complete App Inventor community. Thank you.
Jan 12th, 2021: Version 1: initial version for App Inventor.
Jan 26th, 2021: Version 1a: new keyword URIENCODEDATETIME added
Jan 28th, 2021: Version 1b: new keyword URIENCODECURRENTADDRESS added, new method IsRunning added, properties now return the previously stored values after restarting the app
Location Service Extension
This extension is able to run in the background while your app is closed and stores location data (latitude, longitude and optionally current datetime, altitude, accuracy, speed, current address and provider) in TinyDB.
Also a background web functionality is available which can be used to send the location data to a web service of your choice using a POST request. This could be used for example to store the location data in a MySQL database or to send an email after a location change was detected while the app is not running.
A notifier will be displayed while the location service is running in the background.
Thank you Marco for being the sponsor of this extension!
Minimum API level is 21 (Android 5).
Required permissions: android.permission.FOREGROUND_SERVICE, android.permission.ACCESS_FINE_LOCATION, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_BACKGROUND_LOCATION, android.permission.INTERNET
As the UsesServices annotation meanwhile has been added into Kodular, this extension now also works in Kodular.
However for some reason the RequestLocationPermission method does not work in Kodular. Therefore you have to use the following workaround
which results in getting the following dialog on Android 11. After selecting "while using the app" and starting the service, you get another dialog, after selecting "try again" you then can enable "allow all the time" in the settings app and use the locationservice.
Determines the minimum time interval, in milliseconds, that the sensor will try to use for sending out location updates. However, location updates will only be received when the location of the phone actually changes, and use of the specified time interval is not guaranteed. For example, if 1000 is used as the time interval, location updates will never be fired sooner than 1000ms, but they may be fired anytime after.
Determines the minimum distance interval, in meters, that the sensor will try to use for sending out location updates. For example, if this is set to 5, then the sensor will fire a LocationChanged event only after 5 meters have been traversed. However, the sensor does not guarantee that an update will be received at exactly the distance interval. It may take more than 5 meters to fire an event, for instance.
The tag for TinyDB which should be used to store the location data. The value will be a table in CSV format, which contains the location data, see options below.
After a trip the collected location data could be used for example to display in a map.
As the collected data can be extensive, the following properties can be used to decide, if a specific location information should be stored in TinyDB or not.
Specifies whether the current datetime should be provided as result in TinyDB.
Specifies whether coordinates (latitude and longitude) should be provided as result in TinyDB.
Specifies whether current address should be provided as result in TinyDB.
Specifies whether accuracy should be provided as result in TinyDB.
Specifies whether altitude should be provided as result in TinyDB.
Specifies whether speed should be provided as result in TinyDB.
Specifies whether provider should be provided as result in TinyDB.
The following 4 properties are used to configure the notification, which will be displayed while the location service is running in the background.
SmallIcon for notification. Recommended size is 96x96.
Title to be displayed in the notification.
Text to be displayed in the notification.
Text to be displayed in the shutdown button of the notifier. Default value is 'Shutdown'.
The following properties are used to configure the background web functionality to send a POST request. Also the background web functionality is able to convert keywords into their correponding values. The following keywords are available: DATETIME, URIENCODEDATETIME, LATITUDE, LONGITUDE, ALTITUDE, ACCURACY, SPEED, CURRENTADDRESS, URIENCODECURRENTADDRESS and PROVIDER. See the examples below how this can be used.
Specifies whether background web functionality should be enabled after a location changed event. Default Value is false.
The URL for the web request.
The text for the Post web request.
The request headers, as a list of two-element sublists. The first element of each sublist represents the request header field name. The second element of each sublist represents the request header field value.
Note: You will have to build the app to be able to start the service.
Returns true, if required location permissions have been granted, else false.
Note: It does not really make sense to call that method in the companion app, but it should return false there.
Request Location Permission.
Note: You will have to build the app to be able to request location permission.
Note: For some reason this method does not work in Kodular. Please use the workaround mentioned here.
Android 6 to 9
The user needs to click "Allow" for the location service to be able to run.
The user needs to click "Allow all the time" for the location service to be able to run in the background.
On Android 11 (API level 30) and higher, however, the system dialog doesn't include the Allow all the time option anymore, see also here. Instead, users must enable background location on the settings page.
How to open the settings page programmatically you can use the activity starter, see the example blocks below.
Move task (i.e. the app) to the background.
Note: You will have to build the app to be able to shutdown the service.
Returns true, if location service is running in the background, else false.
Indicates that a new location has been detected. Speed is reported in meters/second.
Note: This event only will fire if the app is up and running.
Indicates that a web request has been executed in the background and a result is available.
Note: This event only will fire if the app is up and running.
Indicates that an Error occurred.
Indicates that service has been started.
For details how to use the web component to send data to a MySQL database,
see my MySQL project here. I used the following CREATE TABLE statement:
CREATE TABLE IF NOT EXISTS location(id VARCHAR(32), now DATETIME, lat FLOAT,lng FLOAT, address varchar(255), PRIMARY KEY(id, now));
The web background functionality will convert the keywords into the correponding values. In the example
the keywords DATETIME, LATITUDE, LONGITUDE and CURRENTADDRESS will be replaced by the current location values.
INSERT INTO location VALUES("1234567", "2020-12-05 14:30:00", 51.5054597, -0.0775452, "Tower Bridge, London")
Note: You can use the Web.UriEncode method only for static values, not for dynamic values provided by the location service extension. There are 2 values, which might need Uri encoding: DATETIME and CURRENTADDRESS, so if you need an Uri encoded DATETIME, use the keyword URIENCODEDATETIME rather than DATETIME and if you need an Uri encoded CURRENTADDRESS, use the keyword URIENCODECURRENTADDRESS rather than CURRENTADDRESS.
|2131899||2022-05-17 11:26:29||32.7022||-79.9667||1629 Folly Rd, Charleston, SC 29412, USA|
|1359489||2022-05-10 13:00:40||37.7796||-122.392||151 Townsend St, San Francisco, CA 94107, USA|
|4235682||2022-04-21 11:25:12||-7.82429||110.477||Jl. Anggrek No.1, Mungur, Jogotirto, Kec. Berbah, Kabupaten Sleman, Daerah Istimewa Yogyakarta 55573, Indonesia|
|6836702||2022-04-21 10:54:04||-7.8243||110.477||Jl. Anggrek No.1, Mungur, Jogotirto, Kec. Berbah, Kabupaten Sleman, Daerah Istimewa Yogyakarta 55573, Indonesia|
|3242658||2022-04-19 01:28:00||37.7796||-122.392||151 Townsend St, San Francisco, CA 94107, USA|
For the Email example I'm using the IFTTT solution, which is described here.
The web background functionality again will convert the key words into the correponding values.
In IFTTT there are 3 variables called VALUE1, VALUE2 and VALUE3 to define: I used VALUE1 as the receiver email address and VALUE2 and VALUE3 are being displayed in the body of the message.
In the example app you can define a tag for TinyDB to store the data for a trip before starting the service. Later or even while the service is still running you can choose one of the tags and display the coordinates in a map. I have chosen the line string component here in the example app.
Tested successfully on Samsung Galaxy A5 running Android 8 and Galaxy A51 running Android 10. I also tested on the following emulators: Nexus 5 running Andrid 5, Nexus 6 running Android 6, Nexus 5X running Android 8 and Xiaomi Redmi Note 7 running Android 9.
Q1: Tips for getting your app approved for background location access
A: See this Google Blog, see also the Google Policy chapter Location Permissions.
Q2: I'm using the following request header and somehow the web background functionality does not work?
A: Please use the ErrorOccurred event to find out, if the defined request header is correct. In your case the following error message will be displayed: Invalid value for RequestHeaders property. This must be a list of sublists. Each sublist must have a key and a value.
Q3: Do I need the Move Task To Back function in order to start the tracing or can the user simply press the O button (go to the home screen of his phone) to start another app?
A: The service starts as soon as the StartService method is executed, this is not dependent on sending the app to the back. Yes, the user also can press the Home button of the device to start another app.
Q4: I need to send latitude and longitude to firebase database in background. How can I do this with your extension?
A: please see again the documentation above, which describes exactly, what the extension can do... which means in your case the extension is not able to store the data in Firebase, but you can use it to store the data in a MySQL database or any other solution, which works with the web component and its Post method.
The test app is available in Google Play. You can test the extension following these steps
You can buy this extension (aix file).
With your payment you accept the terms and conditions below.
Please transfer 12 USD via Paypal
to Pura Vida Apps
After having received your payment I will be happy to send the download link to you. Please let me know your Google account!
I usually will send the download link not later than 24 hours after having received your payment.
Thank you! Taifun