# Android

![Android SDK](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm2.hypertrack.com%2Fcom%2Fhypertrack%2Fsdk-android%2Fmaven-metadata-sdk-android.xml)

## Requirements

* The minimum Android version supported by HyperTrack SDK is `Android 5.0 Lollipop` ([API level 21](https://developer.android.com/tools/releases/platforms#5.0)).
* The minimum supported `targetSdk` is the same as current [minimal value for Google Play submission](https://developer.android.com/google/play/requirements/target-sdk).
* The supported Android CPU architectures ([Android ABIs](https://developer.android.com/ndk/guides/abis)) are: `arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86`. Emulators are also supported.
* You need to have Google Play Services installed on the device for tracking to work. [Huawei HMS Location Kit](https://developer.huawei.com/consumer/en/hms/huawei-locationkit/) is not supported yet.
* HyperTrack SDK uses [Firebase Cloud Messaging Android SDK](https://firebase.google.com/docs/cloud-messaging) as dependency, and minimal version is [23.1.1](https://firebase.google.com/support/release-notes/android#messaging_v23-1-1)

## Basic integration

Updating the SDK? Check out our [CHANGELOG](https://github.com/hypertrack/sdk-android/blob/master/CHANGELOG.md) and [Migration Guide](doc:sdk-migration-guide)  to see what's changed.

### Add HyperTrack SDK to your project

#### Add HyperTrack's Maven repository

Depending on the Gradle version used in the Project use one of the following snippets:

##### With centralized repositories declaration

[Gradle: centralized repositories declaration](https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:centralized-repository-declaration)

This way of managing dependencies was added in Gradle 6.8 and is required by default in Gradle 8.


```groovy settings.gradle
dependencyResolutionManagement {
    ...
    repositories {
        google()
        mavenCentral()
        jcenter()

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

```
```kotlin settings.gradle.kts
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`).


```groovy <module>/build.gradle
repositories {
    maven {
        name 'hypertrack'
        url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
    }
}
```
```kotlin <module>/build.gradle.kts
repositories {
    maven {
        name = 'hypertrack'
        url = 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
    }
}
```
```groovy <project>/build.gradle
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            name 'hypertrack'
            url  'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
        }
    }
}
```
```kotlin <project>/build.gradle.kts
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            name = 'hypertrack'
            url = 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/'
        }
    }
}
```

#### Add HyperTrack SDK dependencies

Add HyperTrack SDK dependencies to the app or module


```groovy build.gradle
dependencies {
    ...
    implementation 'com.hypertrack:sdk-android:<version>'
    implementation 'com.hypertrack:location-services-google:<version>'
    implementation 'com.hypertrack:activity-service-google:<version>'
    implementation 'com.hypertrack:push-service-firebase:<version>'
    ...
}
```
```kotlin build.gradle.kts
dependencies {
    ...
    implementation('com.hypertrack:sdk-android:<version>')
    implementation('com.hypertrack:location-services-google:<version>')
    implementation('com.hypertrack:push-service-firebase:<version>')
    ...
}
```

The latest version: ![SDK-Android](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fm2.hypertrack.com%2Fcom%2Fhypertrack%2Fsdk-android%2Fmaven-metadata-sdk-android.xml)

You can learn more about SDK plugins [here](doc:plugins).

> ⚠️
>
> Because of a known issue in Google Play Services Location library, if you use version 19.0.1 or older you need to use the special version of the HyperTrack SDK Location Services plugin. Check [this FAQ item](#how-to-fix-androidruntime-javalangincompatibleclasschangeerror-found-interface-comgoogleandroidgmslocationfusedlocationproviderclient-but-class-was-expected) for more details.


  ### 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](https://firebase.google.com/docs/android/setup).

To provide HyperTrack the access to sending push messages you need to get a JSON key for a Google Cloud Service account with Firebase access that is connected to your app. You need to upload the key to HyperTrack Dashboard [Setup Page](https://dashboard.hypertrack.com/setup) under *Server to Device communication* section.

If you don't know how to get the key, check the guide: [Getting Google Service account key for Firebase](doc:fcm-service-account)

### Set the publishable key

Get your Publishable Key from the [Setup page](https://dashboard.hypertrack.com/setup).

#### Add PublishableKey to AndroidManifest.xml


```xml AndroidManifest.xml
&lt;?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>
```

### Set Worker Handle

To link a Worker with the device you should set the worker handle:


```
HyperTrack.workerHandle = "user_id" // unique user identifier
```

See [Worker Setup](doc:worker-setup) guide for more information.

### Grant the permissions to the app

The application [has to ask for runtime permissions](https://developer.android.com/training/permissions/requesting) before the SDK will be able to track.

The permissions that are necessary are:

* [android.permission.ACCESS\_FINE\_LOCATION](https://developer.android.com/training/location/permissions)
* [android.permission.ACCESS\_BACKGROUND\_LOCATION](https://developer.android.com/training/location/permissions#background) - only for devices with Android 11 and above (API 30+)

### Start Tracking

Now the app is ready to be tracked from the cloud.

Follow the [Track Work](doc:track-work) tutorial to learn how to control worker tracking from your backend.

### Dashboard

Once your app is running, go to the [dashboard](https://dashboard.hypertrack.com/tracking) where you can see a list of all your devices and their live location with ongoing activity on the map.

## Recommended additional steps

### Identify devices

You can tag devices with names that will make them easy to distinguish them on HyperTrack Dashboard.


```kotlin
   HyperTrack.name = "Device name"
```
```java
   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


```kotlin From JSON String
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
}
```
```kotlin From JSON Map
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


```java From JSON String
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
}
```
```java From JSON Map
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:


```kotlin
// You can use this value to cancel the subscription.
val errorsCancellable: HyperTrack.Cancellable? = null

errorsCancellable = HyperTrack.subscribeToErrors { errors ->
  errors.forEach {
    when(it) {
      is Permissions.Location.Denied -> ...
      is Location.ServicesDisabled -> ...
      ...
    }
  }
}
```

Or by querying the API only when needed:


```kotlin
HyperTrack.errors.forEach {
  when(it) {
    is Permissions.Location.Denied -> ...
    is Location.ServicesDisabled -> ...
    ...
  }
}
```

See [Error API reference](https://hypertrack.github.io/mobile/sdk-android/latest/-hyper-track%20-s-d-k%20for%20-android/com.hypertrack.sdk.android/-hyper-track/-error/index.html) for a full list of errors.

![](/img/readme/3b8209fd4e6a8fdd885f251bc53054dbd34533f434fbdc3953092dd36fa43e14-image.png)

## Reference

For a full SDK API reference see [HyperTrack Android SDK ](https://hypertrack.github.io/mobile/sdk-android/latest/-hyper-track%20-s-d-k%20for%20-android/com.hypertrack.sdk.android/-hyper-track/index.html)

## SDK integration examples

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

* [Quickstart apps](https://hypertrack.com/docs/build-your-app#quickstarts)

## Support

Join our [Slack community](https://join.slack.com/t/hypertracksupport/shared_invite/enQtNDA0MDYxMzY1MDMxLTdmNDQ1ZDA1MTQxOTU2NTgwZTNiMzUyZDk0OThlMmJkNmE0ZGI2NGY2ZGRhYjY0Yzc0NTJlZWY2ZmE5ZTA2NjI) for instant responses.

