Skip to main content

Install SDK on Android

Android SDK

Requirements

  • Android SDK 23 (Android 6.0) or higher
  • compileSdkVersion 31 (Android 12)
  • CPU architectures: arm64-v8a,armeabi-v7a,x86_64
  • Google Play Services (Huawei Services support is planned)

Basic integration

Add Hypertrack SDK to your project

Add following lines to your applications build.gradle:

For Gradle 7.0.0+


settings.gradle

Add Hypertrack repository:

dependencyResolutionManagement {
...
repositories {
google()
mavenCentral()
jcenter()

maven {
name 'hypertrack'
url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
}

App module's build.gradle

Add Hypertrack SDK as a dependency:

dependencies {
...
implementation 'com.hypertrack:hypertrack:<version>'
}

For older Gradle versions


App module's build.gradle

Add Hypertrack repository:

repositories {
...
maven {
name 'hypertrack'
url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}

Add Hypertrack SDK as a dependency:

dependencies {
...
implementation 'com.hypertrack:hypertrack:<version>'
}

For HyperTrack SDK Version 6.0 and 6.1 only

Add android:allowNativeHeapPointerTagging="false" property to your <application> tag in AndroidManifest.xml

We constantly work on making our SDKs better, so make sure you have the latest version. You can get it in the changelog here.

Set up silent push notifications

HyperTrack SDK needs Firebase Cloud Messaging to manage on-device tracking as well as enable using HyperTrack cloud APIs from your server to control the tracking. If you do not yet have push notifications enabled, please proceed to setup Firebase Cloud Messaging.

You need to add your Firebase API key to your HyperTrack Dashboard Setup Page under Server to Device communication section.

In case if you use Firebase Cloud Messaging with version below 21.1.0 along with Proguard you have to add this to your Proguard rules for Hypertrack SDK to work properly:

-keep class com.google.firebase.iid.FirebaseInstanceId {*;}
note

Push notifications have delays so if you're looking for more instant communication channel you can use syncDeviceSettings SDK method to speed up command propagation.

Initialize the SDK

Get your publishable key from the Setup page.

  val sdkInstance = HyperTrack.getInstance("your-publishable-key-here")

Also make sure you've requested permissions somewhere in your app. HyperTrack accesses location and activity data, so exact set of permissions depends on an Android version. You may use HyperTrack.requestPermissionsIfNecessary() convenience method to request permissions and make SDK integration simpler.

Start tracking

Now the app is ready to be tracked from the cloud. HyperTrack gives you powerful APIs to control device tracking from your backend.

To use the HyperTrack API, you will need the {AccountId} and {SecretKey} from the Setup page.

Track devices during work

Track devices when user is logged in to work, or during work hours by calling the Devices API.

To start, call the start API.

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/devices/{device_id}/start

Get the tracking status of the device by calling GET /devices/{device_id} api.

curl \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/devices/{device_id}

To see the device on a map, open the returned embed_url in your browser (no login required, so you can add embed these views directly to you web app). The device will also show up in the device list in the HyperTrack dashboard.

To stop tracking, call the stop API.

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/devices/{device_id}/stop

Track routes with ETA

If you want to track a device on its way to a destination, call the Routes API and add destination.

HyperTrack Trips API offers extra fields to get additional intelligence over the Devices API.

  • set destination to track route and ETA
  • set scheduled_at to track delays
  • share live tracking URL of the trip with customers
  • embed live tracking view of the trip in your ops dashboard
curl -u {AccountId}:{SecretKey} --location --request POST 'https://v3.api.hypertrack.com/trips/' \
--header 'Content-Type: application/json' \
--data-raw '{
"device_id": "{device_id}",
"destination": {
"geometry": {
"type": "Point",
"coordinates": [{longitude}, {latitude}]
}
}
}'

To get {longitude} and {latitude} of your destination, you can use for example Google Maps.

HyperTrack uses GeoJSON. Please make sure you follow the correct ordering of longitude and latitude.

The returned JSON includes the embed_url for your dashboard and share_url for your customers.

When you are done tracking this trip, call complete Trip API using the trip_id from the create trip call above.

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/trips/{trip_id}/complete

After the trip is completed, use the Trips API to retrieve a full summary of the trip. The summary contains the polyline of the trip, distance, duration and markers of the trip.

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/trips/{trip_id}

Dashboard

Once your app is running, go to the dashboard where you can see a list of all your devices and their live location with ongoing activity on the map.

Prepare for Google Play submission

Get approved for the background location access

Android 11 requires background location access in order to start tracking when the app is in background. HyperTrack SDK declares all the required permissions in AndroidManifest.xml but you need to make some changes to your app and its description in Play Console in order to pass the Google Play Review.

Play Console description

Open Play Console select your app from list and scroll the left navigation bar all the way to the bottom. Then select App Content item from Policy section and scroll the page down to Sensitive app permissions section, where you need to click Manage to proceed. Manage Permissions Fill in Policy Compliance form, focusing on user facing aspects of your app. E.g. HyperTrack Visits app uses following:

Input TitleSample Content
App purposeAutomate expense payouts and gather delivery sites coordinates
Location accessRequires all the time location permission to collect data of user movement for the purpose of travel expense payouts (main scenario) based on mileage driven. When the shift ends, it is possible to review the total mileage driven and which path segments contributes to the drives total (walks are not accounted in reimbursement). The latter establishes transparency that is required to trust the automation.
Video instructionshttps://youtu.be/zb55wxCYLCc

Show explanation prompt in the app

Google Play Review team requires that your app show an explanation before permission requests. In case of a background location access the propmpt must contain the following words: This app collects location data to ... even when the app is closed or not in use The flow of requesting permissions should consist of two steps:

  1. App shows permission explanation prompt, containing the sentense above, and requests ACCESS_FINE_LOCATION permission.
  2. Once the previous permission is successfully received, the app should show Adjust Settings prompt and request ACCESS_BACKGROUND_LOCATION permission.


Identify devices

All devices tracked on HyperTrack are uniquely identified using UUID. You can get this identifier programmatically in your app by calling getDeviceId() after initialization.

   val deviceId = sdkInstance.deviceID

Another approach to identification is to tag devices with names that will make it easy to distinguish them on HyperTrack Dashboard.

sdkInstance.setDeviceName("Device name")

You can additionaly tag devices with custom metadata (and filter them in the Dashboard using metadata fields). Metadata should be representable in JSON.

sdkInstance.setDeviceMetadata(mapOf("key" to "value"));

Subscribe to SDK status changes

You can add an SDK state listener to catch events.

You can subscribe to SDK status changes addTrackingListener and handle them in the appropriate methods onError(TrackingError) onTrackingStart() onTrackingStop()

Customize foreground service notification

HyperTrack tracking runs as a separate foreground service, so when it is running, your users will see a persistent notification. By default, it displays your app icon with text {app name} is running but you can customize it anytime after initialization by calling:

  sdkInstance.setTrackingNotificationConfig(
ServiceNotificationConfig.Builder()
.setContentTitle("Tap to stop tracking")
.build()
)

Check out other configurable properties in ServiceNotificationConfig reference

Resolve tracking blockers

In order for tracking to work reliably, SDK requires the user to grant it certain permissions and enable some features in settings. You can use dedicated SDK API to figure out if all the requirements are met: 

val blockers = HyperTrack.getBlockers()
blockers.forEach { blocker ->
Log.d(TAG, "Blocker $blocker requires user to ${blocker.userActionTitle}")
}

Each blocker has a name, a description, CTA name, and an action that is performed when blocker.resolve() is invoked. E.g. Blocker.LOCATION_SERVICE_DISABLED.resolve() triggers navigation to the dedicated Settings menu. Check out Blockers javadoc for details.

Reference

For a full SDK API reference see HyperTrack Android SDK

SDK integration examples

To learn more about SDK integration examples, you may visit these resources:

Support

Join our Slack community for instant responses. You can also email us at help@hypertrack.com.

Frequently Asked Questions

Why my Android APK increased in size after integrating HyperTrack SDK?

  • The HyperTrack Android SDK uses a common compiled binary core, which means that the AAR file of the library contains compiled binaries for 3 different CPU architectures: 64 bit x86, ARM v7a, ARM v8 (AARCH64);

  • We recommend to publish apps using Android App Bundles (AAB documentation). All new apps are required to use this way of packaging in order to be published with Google Play. When using Android App Bundles, the user only downloads the binary slice needed for his CPU architecture, nothing more. This results in much smaller app downloads;

  • With Android App Bundles our Android SDK adds less than 4 MB to the app download size that the user gets from the Play Market;

  • Packaging APK for internal distribution from Android Studio (without Google Play) produces a larger APK. This is because the development distribution contains all 3 binary slices;

  • Google Play Store optimizes app size in the reviewed channels (beta, production). Google Play Store does not optimize size in internal test channels! Size of the app shared via the internal test channel can be larger than the one presented to end users in production channels;

What API levels (Android versions) are supported?

Currently we do support all of the Android versions starting from API 23 (Android 6.0).

Why do I have dependencies conflicts?

Dependency conflicts may arise when the HyperTrack SDK is used together with different libraries. In most cases Gradle automatically resolves all the issues. In some situations, a configuration modification has to be applied to your project.

Detailed information

More information with detailed explanations and instructions can be found here: Gradle documentation

Cheat sheet

  • In case of unresolvable dependency conflicts, please use ./gradlew :your_project_name:dependencies command to see the dependency graph.

  • Usually the dependency graph is full of bumped versions (marked e.g. com.some.dependency:2.0.0 -> com.some.dependency:2.5.0 - Gradle automatically selects the newest version of the transitive dependencies required by other dependencies.

  • If conflicts are visible and cause compilation errors, you can manually exclude the transitive dependencies or downgrade them using: this documentation

  • Common problem here may be depending on different versions of com.android.support library components. You need to migrate to Android X to resolve the issue.

Why do I have persistent notification on my app?

HyperTrack SDK by default runs as a foreground service. This is to ensure that the location tracking works reliably even when your app is minimized.

A foreground service is a service that the user is actively aware of and isn't a candidate for the system to kill when it is low on memory.

Android mandates that a foreground service provides a persistent notification in the status bar. This means that the notification cannot be dismissed by the user.

persistent-notification

How do I handle custom ROMs?

Smartphones are getting more and more powerful, but the battery capacity is lagging behind. Device manufacturers are always trying to squeeze some battery saving features into the firmware with each new Android release. Manufactures like Xiaomi, Huawei and OnePlus have their own battery savers that kills the services running in the background.

To avoid OS killing the service, users of your app need to override the automatic battery management and set it manual.

To inform your users and direct them to the right setting page, SDK shows a special promt on requestPermissionsIfNecessary() invocation.

Unfortunately whitelisting can't be performed programmatically. So you need to always rely on user performing particular action.

In that case the only way to achieve service reliability is manual setup. E.g. for Oxygen OS (OnePlus) you need to select Lock menu item from app options button in Recent Apps view:

one-plus-example

Why does HyperTrack notification show even after my app is terminated?

The HyperTrack service runs as a separate component and it is still running when the app that started it is terminated. That is why you can observe that notification. When you tracking is stopped, the notification goes away.

How does tracking work in Doze mode?

Doze mode requires device to be stationary, so before OS starts imposing power management restrictions, exact device location is obtained. When device starts moving, Android leaves Doze mode and works regularly, so no special handling of Doze mode required with respect to location tracking.

What is AAPT: error: attribute android:foregroundServiceType not found?

If build fails with error like AAPT: error: attribute android:foregroundServiceType not found that means that you're targeting your app for Android P or earlier. To fix this update your build tools and set the target platform as Android 10 (target SDK level 30). Although there are other workarounds to fix the build still targeting earlier versions, starting from Android 10 Google imposes additional restrictions on services, that access location data while phone screen is turned off, so the drawback will be tracking gaps on devices that run Android 10 or later.

Why doesn't setting device metadata and name work in SDK?

Devices API or in PlayGround take precedence over SDK methods in setting device name and metadata. If you used either Devices API or PlayGround, these SDK methods setDeviceMetadata and setDeviceName will not modify device metadata and name.

What is device Id that I get from SDK?

Device ID uniquely identifies SDK installation. Make sure that you stored it on your backend as a part of user profile to be able to identify location data. On Android 8 and later it is always the same for the app + publishable Key pair and persists across the installation. On devices, powered by earlier versions, it could change after reinstall, although there are some cases in which we are able to keep it the same. Anyway, users change devices and can use one login for multiple phones, so you need to handle that logic of updating device ids in backend.

What permissions are required for the SDK to work

SDK requires following permissions:

Most of listed above don't considered dangeourous permissinos, so granted automatically on install. They also included in SDK's AndroidManifest.xml that is mergerd into your app manifest during the build so you no action required from your side. Contrary to that, your app should request permissions from two last paragraphs interactively if it targets API 29 or later and only location permissions, if it targets API 28 or earlier. This could be achieved via sdkInstance.requestPermissionsIfNecessary() method invocation that presents required permissions request dialog, if neccessary, or does nothing, if they were already granted. Background location access permission is special since it cannot be requested interactively, so on Android 11 user is navigated to device's Settings menu where he needs to select Always Allow menu item. HyperTrack SDK shows an info snackbar with message like Please, select "Always Allow" option. with can be customized by overriding ht_background_permission_toast_template string resource. Menu item name is taken from OS APIs (so it will be in user's locale), so you need to leave a template placeholder instead of it like Please, select "%" option..

Since background location permission complicates Google Play Store review process it is recommended to remove it from the manifest if you don't use platfrom based tracking start in your application, using following tag in your AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />

Why in the dashboard I can see sdk killed by user outage reason?

SDK killed also can be a result of some kind of battery saving settings. Unfortunately it's a way too fragmented across the manufacturers, so we can't provide you with exact steps that the user should take to whitelist the app. But in any case users are able to find the exact technique for their brand either on dedicated resources, like https://dontkillmyapp.com/ or phone manufacturer forums.

You may benefit from checking this also.

Can I test functionality without actual movement?

Although HyperTrack SDK ignores mocked locations by default, there are two ways to test its functionality.

The first one is to use standard emulator, that comes with Android Studio. Check the official manual on how to use it. All the emulators have (Emulator) suffix appended to the device-hardware field, so they can be easily identified, if you need it to distinguish between them and real devices.

Another options is to use one of so called Mock Location apps on a real device. It requires phone settings adjustment that usually explained by those apps. To make HyperTrack accept locations from those apps, you also need to pass a special flag, like shown in the snippet below:

val sdkInstance = HyperTrack.getInstance(publishableKey).allowMockLocations()
caution

Make sure the mock data, you feeding to the SDK, looks real. Instant teleport from Delhi to New York doesn't make sense, so those values will be ignored by processing logic, that is present on HyperTrack platform. Make sure you set desired start location before turning the traking on.