A mobile application should only collect a user’s location information if its user experience depends on or is improved by location awareness. An app that delivers retailer-specific coupons or offers based on a user’s location has a valid reason to ask the user for location permissions.
Protecting user privacy and maintaining trust is paramount. The purpose of OpenLocate is to standardize and simplify the collection of location data by mobile applications that have privacy-compliant and user-centric reasons to do so.
OpenLocate should not be used solely to collect location data for monetization purposes.
Here are a couple of blog posts that discuss best practices and things to keep in mind when asking a mobile app user for permissions:
OpenLocate is supported by developers, non-profits, trade groups, and industry for the following reasons:
Mobile application developers can use location data collected via OpenLocate to:
OpenLocate is supported by mobile app developers, non-profit trade groups, academia, and leading companies across GIS, logistics, marketing, and more.
Openlocate uses the following permissions:
OpenLocate initialises a background service alongside your application. This background service collects and transmits location updates.
The location updates rely on Google Play Services' Fused Location Provider
. The location collection interval is set at a default of 5 minutes. Actual location updates received can be more frequent than this however, as OpenLocate will receive passive fixes (location updates triggered by other applications) if there are any.
In order to minimize battery usage and network traffic to your server, the location updates are not transmitted immediately, but rather batched locally for sending at a defined interval. The default transmission interval is six hours. Once successfully transmitted, the location updates are no longer stored on the device.
Add the below line to your app's build.gradle
:
repositories {
maven {
url "https://s3-us-west-2.amazonaws.com/openlocate-android/"
}
}
Add the below line to your app's build.gradle
inside the dependencies
section:
Latested public release
implementation 'com.openlocate:openlocate:2.+'
You can change the following parameters:
OpenLocate.getInstance().setTransmissionInterval(long milliseconds)
specifies the interval at which location records are transmitted from the device. The default is 6 hours. Setting a smaller interval will result in more frequent transmission but higher battery usage.OpenLocate.getInstance().setLocationInterval(long milliseconds)
specifies the maximum interval before which a location update is requested from the device. The default is 5 minutes.OpenLocate.getInstance().setAccuracy(LocationAccuracy)
specifies the accuracy of location updates as described in the Fused Location Provider API. For example:
Configure where the SDK should send data to by building the configuration with appropriate URL and headers. Supply the configuration to the initialize
method. Initialize OpenLocate in the Application
import android.app.Application;
import com.openlocate.android.core.OpenLocate;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
OpenLocate.Configuration config = new OpenLocate.Configuration.Builder(this, BuildConfig.URL)
.setHeaders(<Your Headers>)
.build();
OpenLocate.initialize(config);
}
}
If you would like to send the data to multiple endpoints, you can do so by creating multiple OpenLocate.Endpoint
objects and passing them in to the OpenLocate.Configuration
object. If data fails to be sent to any given endpoint, data will be saved locally and re-tried in later transmissions. A maximum of 10 days worth of data is kept.
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ArrayList<OpenLocate.Endpoint> endpoints = new ArrayList<>();
endpoints.add(OpenLocate.Endpoint.builder(<URL>)
.withHeader("<Header's key>", "Header's value")
.build());
endpoints.add(OpenLocate.Endpoint.builder(<ANOTHER_URL>)
.withHeader("<Another header's key>", " Another header's value")
.build());
OpenLocate.Configuration configuration = new OpenLocate.Configuration.Builder(this, endpoints)
.build();
OpenLocate.initialize(configuration);
}
}
Activity should be passed to method below. Library will request permission for you.
OpenLocate.getInstance().startTracking(activity);
startTracking
method can be called only once: library will restart tracking on next initialization.
To stop location tracking, call the stopTracking
method on OpenLocate
. Get the instance by calling getInstance
.
OpenLocate.getInstance().stopTracking()
The following fields are collected by the SDK to be sent to a private or public API:
latitude
- Latitude of the devicelongitude
- Longitude of the deviceutc_timestamp
- Timestamp of the recorded location in epochhorizontal_accuracy
- The accuracy of the location being recordedid_type
- 'aaid' for identifying android advertising typead_id
- Advertising identifierad_opt_out
- Flag that indicates whether user has enabled "limit ad tracking" (1: enabled; 0: not enabled)course
- Bearing in degrees.speed
- Speed in meters/second over ground.altitude
- Altitude in meters above the WGS 84 reference ellipsoid.is_charging
- Indicates whether phone is charging or notdevice_manufacturer
- Manufacturer of devicedevice_model
- Model of deviseos
- Operating system installed on Device.location_method
- Method of location collected i.e "gps", "network", "passive"location_context
- Indicates whether the location was collected when the application was foregrounded or backgrounded on the device.carrier_name
- Name of the mobile network carrierconnection_type
- Collects devices's network connection typewifi_ssid
- Collects wifi_ssidwifi_bssid
- Collects wifi_bssidOptional field collection can be disabled while building the configuration object before passing it to the initialize
method.
OpenLocate.Configuration configuration = new OpenLocate.Configuration.Builder(context, BuildConfig.URL)
.setHeaders(getHeader())
.withoutDeviceManufacturer()
.withoutDeviceModel()
.withoutChargingInfo()
.withoutOperatingSystem()
.withoutCarrierName()
.withoutConnectionType()
.withoutWifiInfo()
.withoutLocationMethod()
.withoutLocationContext()
.build();
This is a sample request body sent by the SDK.
{
"locations":
[
{
"latitude": 37.773972,
"longitude": -122.431297,
"horizontal_accuracy": "23.670000076293945",
"utc_timestamp": 1508369672,
"course": "0.0",
"speed": "0.0",
"altitude": 0,
"ad_id": "f109e57e-a02e-41d3-b7c4-c906d1b92331",
"ad_opt_out": false,
"id_type": "aaid",
"device_manufacturer": "motorola",
"device_model": "Moto G (5S) Plus",
"is_charging": true,
"os_version": "Android 7.1.1",
"carrier_name": "T Mobile",
"wifi_ssid": "\"Jungle\"",
"wifi_bssid": "10:fe:ed:8d:b5:7c",
"connection_type": "wifi",
"location_method": "gps",
"location_context": "bground"
},
{
"latitude": 37.773972,
"longitude": -122.431297,
"horizontal_accuracy": "23.670000076293945",
"utc_timestamp": 1508369683,
"course": "0.0",
"speed": "0.0",
"altitude": 0,
"ad_id": "f109e57e-a02e-41d3-b7c4-c906d1b92331",
"ad_opt_out": false,
"id_type": "aaid",
"device_manufacturer": "motorola",
"device_model": "Moto G (5S) Plus",
"is_charging": true,
"os_version": "Android 7.1.1",
"carrier_name": "T Mobile",
"wifi_ssid": "\"Jungle\"",
"wifi_bssid": "10:fe:ed:8d:b5:7c",
"connection_type": "wifi",
"location_method": "gps",
"location_context": "bground"
}
]
}
If you want to have the SDK send data to your own AWS s3 environment for example, look into setting up an Kinesis firehose according to the SDK request above.
OpenLocate requires users to accept the Android's Location Permission in order to work correctly. It is therefore important to understand when and how to prompt for the location permission in order to maximize opt-in rates from users. OpenLocate takes care of prompting the location permission atomically for you when the startTracking()
method is invoked. OpenLocate also takes care of remembering this started state across app launches, so you only need to invoke startTracking()
once. You must decide the optimal time to invoke startTracking()
within your app however. Below are a couple of articles that explain the different approaches that can be taken. Ensure you choose one that fits your app’s needs:
This project is licensed under the MIT License - see the LICENSE.md file for details.