---
title: Kotlin
slug: v4-7/kotlin-installing
icon: {"faIcon":"fa-brands fa-korvue"}
docTags: 
createdAt: 2023-07-28T20:16:57.748Z
---

You can integrate the Ditto SDK into Kotlin projects to develop native apps for the Android platform.&#x20;

:::hint{type="info"}
For the API reference, see [ditto 4.7.1](https://software.ditto.live/android/Ditto/4.7.1/api-reference/index.html).
:::

:::hint{type="info"}
For a complete overview of the platforms, transports, and devices the Kotlin SDK supports, see the [compatibility map for Kotlin](docId\:ZFxMLfMZ2kKpGr83SWCOs).
:::

To install the Kotlin SDK and start syncing offline:

::::WorkflowBlock
:::WorkflowBlockItem
Confirm that you meet the minimum requirements. ([Prerequisites](./#prerequisites))
:::

:::WorkflowBlockItem
Prepare your environment for Ditto. ([Setting Up Your Environment](./#setting-up-your-environment))
:::

:::WorkflowBlockItem
Configure your app permissions. ([Configuring Permissions](./#configuring-permissions))
:::

:::WorkflowBlockItem
Authenticate with the Big Peer and then start syncing offline. ([Integrating and Initializing](./#integrating-and-initializing))
:::
::::

# Prerequisites

Following are the minimum requirements that must be met before attempting to install Ditto.

- Android version 6.0 (Marshmallow)
- `minSdk` version 23.0
- `compileSdk` version 34.0
- Java Development Kit (JDK) version 11.0

# Setting Up Your Environment

Include the Maven Central repository in your Gradle file, and then synchronize it with your project.&#x20;

:::::WorkflowBlock
::::WorkflowBlockItem
From your project-level `build.gradle` file located in the `android` root directory, ensure the `mavenCentral()` repository is included in the `buildscript` section:

:::CodeblockTabs
Bash

```none
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // classpath for plugins, etc.
    }
}
```
:::
::::

:::WorkflowBlockItem
Synchronize your project with the Gradle file by clicking **File&#x20;**> **Sync Project with Gradle Files**.
:::
:::::

# Configuring Permissions

The Android operating system limits access to some device functionality for end-user control and privacy.&#x20;

To comply, configure your app to request permissions from end users at once during runtime:

::::WorkflowBlock
:::WorkflowBlockItem
Include all necessary permissions required by Android. ([Including Required Permissions](./#including-required-permissions))
:::

:::WorkflowBlockItem
Proactively check permission availability to avoid unnecessary delay between granting location access and Ditto recognizing the permission. ([Ensuring Permissions Setup](./#ensuring-permissions-setup))
:::
::::

## Including Required Permissions

Android requires certain permissions to be explicitly requested by the app to access features like Bluetooth Low Energy (LE) and Wi-Fi Aware. These permissions must be included in the app's manifest file and requested from the end user at runtime.

:::hint{type="info"}
For more information, see the official [Permissions on Android](https://developer.android.com/guide/topics/permissions/overview) documentation.
:::

To include the necessary permissions required by Android, and then do the following:

:::::WorkflowBlock
:::WorkflowBlockItem
Open the `AndroidManifest.xml` located in the `android/app/src/main` directory of your project.
:::

::::WorkflowBlockItem
Within the `<manifest>` tag, confirm that the following namespace declarations are included and, if needed, add them to the beginning of the file:

:::CodeblockTabs
AndroidManifest.xml

```xml
<manifest
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">
```
:::
::::

::::WorkflowBlockItem
Within the same `<manifest>` tag, just before the `<application>` tag, add the following permissions:

:::CodeblockTabs
AndroidManifest.xml

```xml
<uses-permission android:name="android.permission.BLUETOOTH"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
    android:usesPermissionFlags="neverForLocation"
    tools:targetApi="tiramisu" />
```
:::
::::

::::WorkflowBlockItem
To limit the Android OS from granting select permissions, use the `tools:remove` attribute to selectively exclude specific permissions from being affected by the `android:maxSdkVersion` behavior.

:::hint{type="info"}
Although using `android:maxSdkVersion` prevents unnecessary permission requests on older devices, it can also prevent your app from requesting the permission on devices running a newer Android OS version.

Therefore, before restricting requests, consider how it may impact your app's compatibility and functionality on devices running newer Android OS versions.
:::

For example, the following snippet shows a configuration that requests permissions from end users regardless of the SDK version on the peer device:

:::CodeblockTabs
AndroidManifest.xml

```xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
    tools:remove="android:maxSdkVersion" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
    tools:remove="android:maxSdkVersion" />
```
:::
::::

:::WorkflowBlockItem
Save the `AndroidManifest.xml` file.
:::
:::::

## Confirming SDK Dependency and Version

Ensure that your app’s `build.gradle` file includes the Ditto SDK dependency with the correct version:

:::CodeblockTabs
bash

```none
implementation "live.ditto:ditto:4.7.1"
```
:::

## Ensuring Permissions Setup

To ensure your app has the required permissions for sync, use the `DittoSyncPermissions` helper class from the Ditto SDK. This helper class:

- Simplifies the process of requesting end-user permissions at runtime with a single method call (`ensurePermissions`) for all necessary permissions.
- Handles any errors encountered during the permissions request process.&#x20;

### Using the Helper

To use the `DittoSyncPermissions` helper class:

::::WorkflowBlock
:::WorkflowBlockItem
Import the `DittoSyncPermissions` helper class in the main activity of your app:

```kotlin
import com.ditto.sdk.DittoSyncPermissions
```
:::

:::WorkflowBlockItem
&#x20;Call the following in your `Activity` or Fragment's `onCreate` method:

```kotlin
fun checkPermissions() {
    val missing = DittoSyncPermissions(this).missingPermissions()
    if (missing.isNotEmpty()) {
        this.requestPermissions(missing, 0)
    }
}
```
:::

:::WorkflowBlockItem
Refresh permissions after location access.

On Android, after granting location access, Ditto may not immediately recognize the permission, causing a delay in syncing. To address this, whenever a relevant permission changes, call `refreshPermissions()` to quickly check and start syncing with the new permissions:

```kotlin
fun checkPermissions() {
    val activity = requireActivity()
    val missing = DittoSyncPermissions(activity).missingPermissions()
    if (missing.isNotEmpty()) {
        activity.requestPermissions(missing, 0)
    }
}
```
:::
::::

# Integrating and Initializing

Using the Application-level Context, integrate Ditto into your app's `onCreate` method. 

Most apps require that Ditto run as a *singleton*. A singleton is an implementation ensuring your Ditto instance accesses and shares a single object instance throughout your app.


To import the Ditto instantiate ditto as a singleton object, create a custom Application class subclass with the necessary initialization setup\:Ceate and manage the Ditto instance within the `Application` class of your Android app. integrate Ditto into your app's `onCreate` method. 

:::hint{type="info"}
cBy doing so, you ensure that there is only one instance of Ditto throughout the app's lifecycle, and it remains available for use by any activity or component that needs it. This approach helps in efficient resource management and avoids unnecessary object instantiation and destruction.
:::



:::::WorkflowBlock
::::WorkflowBlockItem
Add Ditto to your application by placing it in your `Application.onCreate` method.

:::hint{type="warning"}
To ensure your app maintains a single Ditto instance throughout its lifetime and prevents it from going out of scope or getting garbage collected, place Ditto in the `Application level` `Context` instead of the `Context` from any activity where you initially instantiated the Ditto instance.
:::

```kotlin
try {
    val androidDependencies = DefaultAndroidDittoDependencies(context)
    val identity = DittoIdentity.OnlinePlayground(
        androidDependencies,
        appId = "REPLACE_ME_WITH_YOUR_APP_ID",
        token = "REPLACE_ME_WITH_YOUR_PLAYGROUND_TOKEN"
    )
    DittoLogger.minimumLogLevel = DittoLogLevel.DEBUG
    ditto = Ditto(androidDependencies, identity)
    ditto.startSync()
} catch (e: DittoError) {
    Log.e("Ditto error", e.message!!)
}
```
::::

:::WorkflowBlockItem
Replace `YOUR_APP_ID` and `YOUR_PLAYGROUND_TOKEN` with your access credentials available from the portal. (See [Sync Credentials](docId:061yVO55q5YRBtWj5BSXC))
:::
:::::

