Awesome Open Source
Awesome Open Source

OpenLocate

Purpose

Why should you collect location data?

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:

Why is this project useful?

OpenLocate is supported by developers, non-profits, trade groups, and industry for the following reasons:

  • Collecting location data in a battery efficient manner that does not adversely affect mobile application performance is non-trivial. OpenLocate enables everyone in the community to benefit from shared knowledge around how to do this well.
  • Creates standards and best practices for location collection.
  • Developers have full transparency on how OpenLocate location collection works.
  • Location data collected via OpenLocate is solely controlled by the developer.

What can I do with location data?

Mobile application developers can use location data collected via OpenLocate to:

  • Enhance their mobile application using context about the user’s location.
  • Receive data about the Points of Interest a device has visited by enabling integrations with 3rd party APIs such as Google Places or Foursquare Venues
  • Send location data to partners of OpenLocate via integrations listed here.

Who is supporting OpenLocate?

OpenLocate is supported by mobile app developers, non-profit trade groups, academia, and leading companies across GIS, logistics, marketing, and more.

Requirements

  • Android - Min SDK version 19

Permissions

Openlocate uses the following permissions:

  • ACCESS_COARSE_LOCATION - Required to access approximate location.
  • ACCESS_FINE_LOCATION - Required to access precise location.
  • INTERNET - Required to open network sockets.
  • ACCESS_WIFI_STATE - Required to access information about Wi-Fi networks.

How OpenLocate Works

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.

Installation

Adding to your project

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.+'

Usage

Optional configuration

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:
    • PRIORITY_HIGH_ACCURACY: this will return the finest location available e.g. more likely to use GPS
    • PRIORITY_BALANCED_POWER_ACCURACY: returns approximately block-level accuracy (~100m)

Initialization

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);
    }
}

Configuring multiple endpoints

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);
     }
}

Start tracking:

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.

Stop tracking of location

To stop location tracking, call the stopTracking method on OpenLocate. Get the instance by calling getInstance.

OpenLocate.getInstance().stopTracking()

Fields collected by the SDK

The following fields are collected by the SDK to be sent to a private or public API:

  1. latitude - Latitude of the device
  2. longitude - Longitude of the device
  3. utc_timestamp - Timestamp of the recorded location in epoch
  4. horizontal_accuracy - The accuracy of the location being recorded
  5. id_type - 'aaid' for identifying android advertising type
  6. ad_id - Advertising identifier
  7. ad_opt_out - Flag that indicates whether user has enabled "limit ad tracking" (1: enabled; 0: not enabled)
  8. course - Bearing in degrees.
  9. speed - Speed in meters/second over ground.
  10. altitude - Altitude in meters above the WGS 84 reference ellipsoid.
(Optional)
  1. is_charging - Indicates whether phone is charging or not
  2. device_manufacturer - Manufacturer of device
  3. device_model - Model of devise
  4. os - Operating system installed on Device.
  5. location_method - Method of location collected i.e "gps", "network", "passive"
  6. location_context - Indicates whether the location was collected when the application was foregrounded or backgrounded on the device.
  7. carrier_name - Name of the mobile network carrier
  8. connection_type - Collects devices's network connection type
  9. wifi_ssid - Collects wifi_ssid
  10. wifi_bssid - Collects wifi_bssid

Configuring fields for collection

Optional field collection can be disabled while building the configuration object before passing it to the initialize method.

For example

OpenLocate.Configuration configuration = new OpenLocate.Configuration.Builder(context, BuildConfig.URL)
                    .setHeaders(getHeader())
                    .withoutDeviceManufacturer()
                    .withoutDeviceModel()
                    .withoutChargingInfo()
                    .withoutOperatingSystem()
                    .withoutCarrierName()
                    .withoutConnectionType()
                    .withoutWifiInfo()
                    .withoutLocationMethod()
                    .withoutLocationContext()
                    .build();

Sample Request Body

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.

Location Permission Opt-In Best Practices

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:

Communication

  • If you need help, post a question to the discussion forum, or tag a question with 'OpenLocate' on Stack Overflow.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.


Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
java (31,734
location (93
android-sdk (74
location-services (17