
Amplitude's latest Android SDK (`com.amplitude:analytics-android`) uses Kotlin and features a plugin architecture and built-in type definitions. The latest Android SDK isn't backward compatible with the maintenance Android SDK `com.amplitude:android-sdk`.

To migrate to `com.amplitude:analytics-android`, update your dependencies and instrumentation.

## Terminology

- `com.amplitude:android-sdk`: Maintenance Android SDK.
- `com.amplitude:analytics-android`: Latest Android SDK.

## Dependency

Update `build.gradle` to remove the maintenance Android SDK and add the latest Android SDK. Then sync the project with Gradle files.

```java
dependencies {
  implementation 'com.amplitude:android-sdk:2.+'
  implementation 'com.squareup.okhttp3:okhttp:4.2.2'
  implementation 'com.amplitude:analytics-android:1.+'
}
```

## Instrumentation

The latest Android SDK offers a new API to instrument events. To migrate, update a few calls. The following sections detail which calls have changed.

### Initialization

Initialize the SDK with a valid Amplitude API Key and Android application context.

{% code-group %}
```kotlin Kotlin
import com.amplitude.api.Amplitude
import com.amplitude.api.AmplitudeClient
import com.amplitude.android.Amplitude

val client = Amplitude.getInstance()
  .initialize(getApplicationContext(), "YOUR_API_KEY")
val client = Amplitude(
    Configuration(
        apiKey = "YOUR_API_KEY",
        context = getApplicationContext()
    )
)
```

```java Java
import com.amplitude.api.Amplitude;
import com.amplitude.api.AmplitudeClient;
import com.amplitude.android.Amplitude;

AmplitudeClient client = Amplitude.getInstance()
  .initialize(getApplicationContext(), "YOUR_API_KEY");
Amplitude client =  new Amplitude(new Configuration(
    apiKey = "YOUR_API_KEY",
    context = getApplicationContext()
));
```
{% /code-group %}

### Configuration

The latest Android SDK uses a different configuration shape. The latest SDK doesn't support some configurations.

| com.amplitude:android-sdk      | com.amplitude:analytics-android                                                                                                                                                                                                 |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `eventUploadPeriodMillis`      | `flushIntervalMillis`                                                                                                                                                                                                           |
| `eventUploadThreshold`         | `flushQueueSize`                                                                                                                                                                                                                |
| `eventUploadMaxBatchSize`      | Not supported                                                                                                                                                                                                                   |
| `eventMaxCount`                | Not supported                                                                                                                                                                                                                   |
| `identifyBatchIntervalMillis`  | `identifyBatchIntervalMillis`                                                                                                                                                                                                   |
| `flushEventsOnClose`           | `flushEventsOnClose`                                                                                                                                                                                                            |
| `optOut`                       | `optOut`                                                                                                                                                                                                                        |
| `trackingSessionEvents`        | `trackingSessionEvents`                                                                                                                                                                                                         |
| `sessionTimeoutMillis`         | Not supported. The maintenance SDK disables foreground tracking by default and uses `sessionTimeoutMillis` when you disable foreground tracking. The latest SDK enables foreground tracking and doesn't expose this setting. |
| `minTimeBetweenSessionsMillis` | `minTimeBetweenSessionsMillis`                                                                                                                                                                                                  |
| `serverUrl`                    | `serverUrl` defaults to `https://api2.amplitude.com/2/httpapi` while the maintenance SDK defaults to `https://api2.amplitude.com/`                                                                                              |
| `useDynamicConfig`             | Not supported                                                                                                                                                                                                                   |

### Send events

The `logEvent()` API maps to `track()`. The maintenance SDK uses `JSONObject` for `eventProperties`. The latest SDK uses `Map<String, Any?>`.

{% code-group %}
```kotlin Kotlin
import org.json.JSONException
import org.json.JSONObject

val eventProperties = JSONObject()
try {
  eventProperties.put("buttonColor", "primary")
} catch (e: JSONException) {
  System.err.println("Invalid JSON")
  e.printStackTrace()
}
client.logEvent("Button Clicked", eventProperties)

client.track(
    "Button Clicked",
    mutableMapOf<String, Any?>("buttonColor" to "primary")
)
```

```java Java
import org.json.JSONException;
import org.json.JSONObject;

JSONObject eventProperties = new JSONObject();
try {
  eventProperties.put("buttonColor", "primary");
} catch (JSONException e) {
  System.err.println("Invalid JSON");
  e.printStackTrace();
}
client.logEvent("Button Clicked", eventProperties);

client.track("Button Clicked", new HashMap()
    put("buttonColor", "primary");
);
```
{% /code-group %}

### Flush events

By default, the SDK buffers unsent events and flushes them when the app closes. The SDK flushes events when it reaches either `flushIntervalMillis` or `flushQueueSize`, whichever comes first.

To disable flushing on close, set `flushEventsOnClose` to `false`.

You can also force the SDK to upload unsent events. The `uploadEvents()` API maps to `flush()`.

```kotlin
client.uploadEvents()
client.flush()
```

### Set user properties

The `identify()` API remains the same.

{% code-group %}
```kotlin Kotlin
val identify = Identify()
identify.set("location", "LAX")
client.identify(identify)
```

```java Java
Identify identify = new Identify();
identify.set("location", "LAX");
client.identify(identify);
```
{% /code-group %}

### Set group properties

{% code-group %}
```kotlin Kotlin
val groupType = "plan"
val groupName = "enterprise"

val identify = Identify().set("key", "value")
client.groupIdentify(groupType, groupName, identify)
```

```java Java
String groupType = "plan";
Object groupName = "enterprise";

Identify identify = new Identify().set("key", "value");
client.groupIdentify(groupType, groupName, identify);
```
{% /code-group %}

### Track revenue

The `logRevenueV2()` API maps to `revenue()`.

{% code-group %}
```kotlin Kotlin
val revenue = Revenue()
revenue.productId = "com.company.productId"
revenue.price = 3
revenue.quantity = 2
client.logRevenueV2(revenue)
client.revenue(revenue)
```

```java Java
Revenue revenue = new Revenue()
revenue.setProductId("com.company.productId");
revenue.setPrice(3);
revenue.setQuantity(2);
client.logRevenueV2(revenue);
client.revenue(revenue);
```
{% /code-group %}

#### Revenue verification

Amplitude's backend handles revenue verification logic. Revenue verification remains functional after you migrate to the latest Android SDK.

## Advanced topics

{% callout type="warning" heading="" %}
The maintenance SDK uses an old SDK endpoint (`api2.amplitude.com`) that enforces no length limit for `deviceId` and `userId`. The latest SDK uses Amplitude's HTTP V2 API (`api2.amplitude.com/2/httpapi`) and requires identifiers of at least 5 characters by default. When you migrate to the latest SDK, set `config.minIdLength` to a smaller value if you allow identifiers with fewer than 5 characters.
{% /callout %}

Most behaviors of the latest SDK match the maintenance SDK. Refer to the advanced topics sections of the [maintenance SDK](/docs/sdks/analytics/android/android-sdk#advanced-topics) and the [latest SDK](/docs/sdks/analytics/android/android-kotlin-sdk) to learn more about a specific topic.

## Data migration

By default, the latest SDK imports existing [maintenance SDK](/docs/sdks/analytics/android/android-sdk) data, including events and user or device IDs. To disable this behavior, set `migrateLegacyData` to `false` in the [Configuration](#configuration). Learn more in [GitHub](https://github.com/amplitude/Amplitude-Kotlin/blob/main/android/src/main/java/com/amplitude/android/migration/RemnantDataMigration.kt#L9-L16).

{% code-group %}
```kotlin Kotlin
amplitude = Amplitude(
    Configuration(
        ...
        migrateLegacyData = false,
    )
)
```

```java Java
Configuration configuration = new Configuration("AMPLITUDE_API_KEY", getApplicationContext());
configuration.setMigrateLegacyData(false);

Amplitude amplitude = new Amplitude(configuration);
```
{% /code-group %}
