Android
Requirements
- The minimum OS supported by the HyperTrack SDK is Lollipop (API level 19).
- The HyperTrack SDK is compiled for the OS version Tiramisu (API level 33).
- The targeted OS is Snow Cone (API level 31).
- Please keep in mind the official Google Play's target API level requirements and apply them to the project that uses the HyperTrack SDK-Android
- The supported Android CPU architectures (Android ABIs) are:
arm64-v8a
,armeabi-v7a
,x86_64
,x86
,
- The supported Location Services are:
- Google Play-Services-Location
- Huawei HMS Location Kit is not supported yet
- The supported Push Notification Services are:
Basic integration
Migrating from older versions? Check the Migration guide
Add HyperTrack SDK to your project
We constantly work on making our SDKs better, so make sure you have the latest version. You can get it in the changelog here.
Add HyperTrack's Maven repository
Depending on the Gradle version used in the Project use one of the following snippets:
This way of managing dependencies was added in Gradle 6.8 and is required by default in Gradle 8.
dependencyResolutionManagement {
...
repositories {
google()
mavenCentral()
jcenter()
maven {
name 'hypertrack'
url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
}
dependencyResolutionManagement {
...
repositories {
google()
mavenCentral()
jcenter()
maven {
name = 'hypertrack'
url = 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
}
Without centralized repositories declaration
Add the repository to your module-level Gradle config (usually app/build.gradle
) and project-level one (<project folder>/build.gradle
).
repositories {
maven {
name 'hypertrack'
url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
repositories {
maven {
name = 'hypertrack'
url = 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
allprojects {
repositories {
google()
mavenCentral()
maven {
name 'hypertrack'
url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
}
allprojects {
repositories {
google()
mavenCentral()
maven {
name = 'hypertrack'
url = 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
}
}
}
Add HyperTrack SDK dependency
Add HyperTrack SDK as a dependency to the app or module
dependencies {
...
implementation 'com.hypertrack:sdk-android:<version>'
...
}
dependencies {
...
implementation('com.hypertrack:sdk-android:<version>')
...
}
The latest version:
The plugins should have the same version as the main SDK dependency
Add HyperTrack SDK Location Services plugin
HyperTrack SDK gives a possibility to choose from a variety of Location Services implementations.
At least one plugin of Location Services type is required for the SDK to work.
For devices with Google Play Services
dependencies {
...
implementation 'com.hypertrack:location-services-google:<version>'
...
}
dependencies {
...
implementation('com.hypertrack:location-services-google:<version>')
...
}
For devices with Google Play Services which require older Location Services
If the target application / module uses older Google Location Services dependencies and a conflict in class definitions results in build or runtime failures (e.g. for pre 21.0.0 versions as states in official Release Notes by Google):
One of the Exceptions that happens with incompatible versions of Google Location Services is:
AndroidRuntime: java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.FusedLocationProviderClient, but class was expected
There is a special version to overcome the build issue:
dependencies {
...
implementation 'com.hypertrack:location-services-google-19-0-1:<version>'
...
}
dependencies {
...
implementation('com.hypertrack:location-services-google-19-0-1:<version>')
...
}
Add HyperTrack SDK Push Services plugin
At least one plugin of Push Services type is required for the SDK to work.
For projects with Firebase Cloud Messaging
dependencies {
...
implementation 'com.hypertrack:push-service-firebase:<version>'
...
}
dependencies {
...
implementation('com.hypertrack:push-service-firebase:<version>')
...
}
You can check the full list of plugins here
After adding dependencies make sure you run
Sync Project with Gradle Files
!
Configure Proguard
Make sure you are using the latest SDK version.
If you use Proguard (have minifyEnabled true
in your app build.gradle
) add these lines to your proguard-rules.pro
:
# config for kotlin-coroutines
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
-keepclassmembernames class kotlinx.** {
volatile <fields>;
}
-keep class kotlinx.coroutines.android.AndroidDispatcherFactory {*;}
Set up silent push notifications
HyperTrack SDK requires Firebase Cloud Messaging to:
- Manage on-device tracking
- Enable HyperTrack cloud APIs usage to control the tracking from your server
- Waking up the app if it was killed by the device OS
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.
You can get this key in Firebase Console
> Settings
> Project Settings
> Cloud Messaging
> Cloud Messaging API (Legacy)
> Server key
If you don't see the key entry there, make sure you have admin
rights in your Firebase project.
Set the publishable key
Get your Publishable Key from the Setup page.
Add PublishableKey to AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:name=".AnApplication">
<meta-data
android:name="HyperTrackPublishableKey"
android:value="put-your-key-here" />
</application>
</manifest>
Grant the permissions to the app
The application has to ask for runtime permissions before the SDK will be able to track.
The permissions that are necessary are:
- android.permission.ACCESS_FINE_LOCATION
- android.permission.ACCESS_BACKGROUND_LOCATION - only for devices with Android 11 and above (API 30+)
- android.permission.POST_NOTIFICATIONS - only for for devices with Android 13 and above (API 33+)
Start tracking
Now the app is ready to be tracked from the cloud.
You will need the device id to start tracking, check the Identify devices section for instructions on how to get it.
Follow the Start Tracking tutorial to learn how to control device tracking from your backend.
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
- Scroll the left navigation bar all the way to the bottom. Then select App Content item from Policy section
- Scroll the page down to Location permissions section
- Click Manage to proceed
- Fill in Policy Compliance form, focusing on user facing aspects of your app. E.g. HyperTrack Visits app uses following:
Input Title | Sample Content |
---|---|
App purpose | Automate expense payouts and gather delivery sites coordinates |
Location access | Requires 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. |
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:
- App shows permission explanation prompt, containing the sentense above, and requests
ACCESS_FINE_LOCATION
permission. - Once the previous permission is successfully received, the app should show Adjust Settings prompt and request
ACCESS_BACKGROUND_LOCATION
permission.
Video example of proper permission experience
Check more details in official Google docs:
- Google support on background location permission
- PlayAcademy course on how to make prominent disclosures
- PlayAcademy on location permissions policies
- PlayAcademy on how to provide the data for the Google Play review
Recommended additional steps
Identify devices
All devices tracked on HyperTrack are uniquely identified using UUID. You can get this identifier programmatically in your app by calling getDeviceId()
.
The device ID is changed on each app re-install or clearing the app data
val deviceId = HyperTrack.deviceID
String deviceId = HyperTrack.getDeviceID();
Another approach to identification is to tag devices with names that will make it easy to distinguish them on HyperTrack Dashboard.
HyperTrack.name = "Device name"
HyperTrack.setName("Device name");
You can additionaly tag devices with custom metadata (and filter them in the Dashboard using metadata fields).
Metadata should be representable with a map of JSON data types.
You need to build a special Json.Object
data type to send the data to the SDK. This type ensures that the format is JSON-compatible. There are 2 helper methods to build this object from Map or JSON string, but you can build it manually too using the constructor methods.
Kotlin
import com.hypertrack.sdk.android.Json
val metadataJson: Json? = Json.fromString("{ \"key\":\"value\" }")
if(metadataJson != null) {
HyperTrack.metadata = metadataJson
} else {
// You will get the null value if provided String is not a valid JSON
}
import com.hypertrack.sdk.android.Json
val metadataJson: Json? = Json.fromMap(mapOf("key" to "value"))
if(metadataJson != null) {
HyperTrack.metadata = metadataJson
} else {
// You will get the null value if provided Map is not a valid JSON Map
}
Java
import com.hypertrack.sdk.android.Json
Json.Object metadataJson = Json.Companion.fromString("{ \"key\":\"value\" }")
if(metadataJson != null) {
HyperTrack.setMetadata(metadataJson)
} else {
// You will get the null value if provided String is not a valid JSON
}
import com.hypertrack.sdk.android.Json
Map myMetadata = new HashMap<String, Object>()
myMetadata.put("key", "value")
Json.Object metadataJson = Json.Companion.fromMap(myMetadata)
if(metadataJson != null) {
HyperTrack.setMetadata(metadataJson)
} else {
// You will get the null value if provided Map is not a valid JSON Map
}
Handle errors
Use the errors
query or subscribeToErrors
subscription to make sure that when the driver navigates to the screen where tracking is supposed to happen, there are no blockers that can interrupt it.
You can use subscription API to be able to react immediately when errors come up:
// You can use this value to cancel the subscription.
val errorsCancellable: HyperTrack.Cancellable? = null
errorsCancellable = HyperTrack.subscribeToErrors { errors ->
errors.forEach {
when(it) {
is Permissions -> ...
...
}
}
}
Or by querying the API only when needed:
HyperTrack.errors.forEach {
when(it) {
is Permissions -> ...
...
}
}
Check the API docs to get the full list of errors.
Migration guide
Version < 7.0.0
The release of HyperTrack Android SDK 7.0.0 is a major update that has a bunch of new improvements. We highly recommend upgrading, but please note that there are a few breaking changes.
The key advantages of the new version are:
User-friendly API:
The revamped static API is the highlight, standing out for its unmatched simplicity, ease of use, and conciseness.
Enhanced Responsiveness & Speed:
Experience quicker time to the first location and minimized system latency.
Superior Tracking Performance:
Delight in the improved quality, granularity, and accuracy of the location event stream.
Optimized Battery Efficiency:
Our refined tracking algorithm reduces unnecessary network calls, preserving battery life.
Decreased Binary Size:
The library's size optimization ensures a more compact overall app footprint.
You can check the detailed Changelog here
The key breaking changes are:
Setting the publishable key
There is no need to initialize the SDK by setting publishable key. The Basic integration instructions decribe the new way of setting it.
Static API
The SDK API was fully redesigned to be more ergonomic and to require less code to use.
All the API methods can be accessible at any time from any place in the app by calling them on the static HyperTrack
class.
Check the Changelog for the renamed methods.
New Maven artifact ID
The old dependency in build.gradle
should be removed:
implementation "com.hypertrack:hypertrack:${version}"
Follow the Add HyperTrack SDK to your project tutorial to configure the new SDK.
ACTIVITY_RECOGNITION
permission is no longer required
ACTIVITY_RECOGNITION
permission is no longer requiredWhile the SDK still can benefit from Motion activity data to get better accuracy, requesting this permission is now optional.
Make sure you implement requests for all permissions: Grant the permissions to the app
SDK Sync
The SDK is now automatically syncs with the servers, so the syncDeviceSettings()
method is not needed. You can safely remove it and all the logic related to it.
New Json.Object param type for addGeotag
and metadata
addGeotag
and metadata
In the new version you need to build a special Json.Object
object to send the data to the SDK.
Check the Identify devices metadata
section for details on how to use it.
New nested HyperTrack.Error
In older versions there were 2 ways to get the SDK errors:
- With
addTrackingListener()
/addAvailabilityListener()
onError
callback - With Blockers API
HyperTrack.getBlockers()
In the new version both of the APIs above are removed and replaced with Errors API (HyperTrack.errors
/HyperTrack.subscrbeToErrors()
)
Check the Handle errors section for the details on how to use that API.
Here is the table of correspondence between the TrackingError
/Blocker
and according HyperTrack.Error types:
Old Error | HyperTrack.Error |
---|---|
TrackingError.UNKNOWN_ERROR | -- removed -- |
TrackingError.INVALID_PUBLISHABLE_KEY_ERROR | Error.InvalidPublishableKey |
TrackingError.AUTHORIZATION_ERROR | -- removed -- |
TrackingError.PERMISSION_DENIED_ERROR | Error.Permissions.Location.Denied |
TrackingError.GPS_PROVIDER_DISABLED_ERROR | Error.Location.ServicesDisabled |
TrackingError.UNKNOWN_NETWORK_ERROR | -- removed -- |
TrackingError.DATA_STORE_ERROR | -- removed -- |
Blocker.LOCATION_PERMISSION_DENIED | Error.Permissions.Location.Denied |
Blocker.LOCATION_SERVICE_DISABLED | Error.Location.ServicesDisabled |
Blocker.ACTIVITY_PERMISSION_DENIED | -- removed -- |
Blocker.BACKGROUND_LOCATION_DENIED | Error.Permissions.Location.Denied |
OutageReason.MISSING_LOCATION_PERMISSION | Error.Permissions.Location.Denied |
OutageReason.MISSING_ACTIVITY_PERMISSION | -- removed -- |
OutageReason.LOCATION_SERVICE_DISABLED | Error.Location.ServicesDisabled |
OutageReason.NOT_TRACKING | LocationError.NotRunning |
OutageReason.START_HAS_NOT_FINISHED | LocationError.Starting |
OutageReason.NO_GPS_SIGNAL | Error.Location.SignalLost |
OutageReason.RESTART_REQUIRED | -- removed -- |
Version < 6.3.0
From the version 6.3.0 The device ID doesn't persist between installs similar to iOS SDK
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.
Frequently Asked Questions
What API levels (Android versions) are supported?
Check Requirements section.
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 there are bumped versions in dependency graph (marked like
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.
How do I handle system battery saver killing my app?
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.
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.
Check dontkillmyapp.com for the instructions on how to whitelist the app.
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.
Why doesn't setting device metadata and name work in SDK?
Devices API take precedence over SDK methods in setting device name and metadata. If you used it, theSDK methods will not modify device metadata and name.
What runtime permissions are required for the SDK to work?
Chech the Grant permissions section
Why in the dashboard I can see SDK killed by ...
outage reason?
SDK killed by ...
outage reason?SDK killed also can be a result of some kind of battery saving settings. Check How do I handle system battery saver killing my app?
You may benefit from checking this also.
Can I test functionality without actual movement?
There are two ways to test the tracking:
-
Use the emulator. Check the official manual on how to use it.
-
Use Mock Location apps on a real device. It requires phone settings adjustment that usually explained by those apps. If using such apps, you will get
Location Mocked
outage in the dashboard and corresponding Error inHyperTrack.errors
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 on the HyperTrack platform. Make sure you set desired start location before turning the traking on.
Updated about 5 hours ago