> For the complete documentation index, see [llms.txt](https://multiset.gitbook.io/multiset/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://multiset.gitbook.io/multiset/native-support/android-native/sample-activities/mainactivity.md).

# MainActivity

## Overview

The `MainActivity` serves as the entry point for the MultiSet SDK demo application. It demonstrates SDK initialization, authentication handling, and navigation to the AR localization activity.

## Description

This activity is responsible for:

1. Initializing the MultiSet SDK with credentials
2. Handling the authentication flow
3. Managing camera and ARCore permissions
4. Launching the unified `MultiSetLocalizationActivity` for single-frame or multi-frame localization
5. Launching `ObjectTrackingActivity` for AR object detection and tracking

The landing page uses a card-based layout:

* **Settings Gear** — top-right icon that opens the [Settings dialog](/multiset/native-support/android-native/api-reference/localizationconfig.md#runtime-settings-dialog) to edit localization & object-tracking configuration at runtime
* **Auth Button** — full-width, shows authentication state
* **Localization Card** — displays map code, a mode toggle (Single Frame / Multi Frame), and a Start Localization button
* **Object Tracking Card** — displays configured object codes and a Start Object Tracking button

***

## Authentication Flow

### 1. SDK Initialization

The SDK is initialized using credentials from `BuildConfig`:

```kotlin
val config = MultiSetConfig.Builder(clientId, clientSecret)
    .mapCode(mapCode)           // or .mapSetCode(mapSetCode)
    .enableMeshVisualization(true)
    .backgroundLocalization(true)
    .build()

MultiSetSDK.initialize(this, config, this)
```

### 2. Configuration Builder Options

| Method                             | Description                                            |
| ---------------------------------- | ------------------------------------------------------ |
| `mapCode(String)`                  | Set a single map code for localization                 |
| `mapSetCode(String)`               | Set a mapSet code for localizing against multiple maps |
| `enableMeshVisualization(Boolean)` | Enable/disable 3D mesh overlay visualization           |
| `backgroundLocalization(Boolean)`  | Enable/disable background localization                 |

### 3. Authentication Callbacks

The activity implements `MultiSetCallback` to receive authentication events:

```kotlin
override fun onSDKReady() {
    // SDK is initialized, authentication in progress
}

override fun onAuthenticationSuccess() {
    // Authentication successful, ready for localization
    // Enable localization buttons
}

override fun onAuthenticationFailure(error: String) {
    // Authentication failed
    // Show error message and enable retry
}
```

***

## APIs Used for Authentication

### MultiSetSDK

| Method                                              | Description                                               |
| --------------------------------------------------- | --------------------------------------------------------- |
| `MultiSetSDK.initialize(context, config, callback)` | Initializes the SDK with configuration and callback       |
| `MultiSetSDK.getLastLocalizationResult()`           | Returns the last successful `LocalizationResult`, or null |

### MultiSetConfig.Builder

| Method                             | Parameters       | Description                                      |
| ---------------------------------- | ---------------- | ------------------------------------------------ |
| `Builder(clientId, clientSecret)`  | `String, String` | Creates a configuration builder with credentials |
| `mapCode(code)`                    | `String`         | Sets the map code for single-map localization    |
| `mapSetCode(code)`                 | `String`         | Sets the mapSet code for multi-map localization  |
| `enableMeshVisualization(enabled)` | `Boolean`        | Enables mesh visualization after localization    |
| `backgroundLocalization(enabled)`  | `Boolean`        | Enables background localization                  |
| `build()`                          | -                | Builds the configuration object                  |

***

## Public Methods

### setupUI()

Initializes the UI components and sets up button click listeners:

* Authentication button (retry on failure)
* Mode toggle group (Single Frame / Multi Frame selection)
* Start Localization button
* Start Object Tracking button
* Settings gear (opens `SettingsDialogFragment` to edit `LocalizationConfig` / `ObjectTrackingConfig` at runtime)

> Persisted configuration is restored before any AR activity reads it: `MainActivity.onCreate()` calls `ConfigStore.load(this)`, which applies the values saved from the Settings dialog. Credentials and map / object codes are always sourced from `multiset.properties` and are never persisted.

### initializeSDK()

Initializes the MultiSet SDK with credentials from `BuildConfig`:

* Validates that `clientId` and `clientSecret` are configured
* Validates that either `mapCode` or `mapSetCode` is configured
* Builds the SDK configuration
* Calls `MultiSetSDK.initialize()`

### checkCameraPermission()

Checks and requests camera permission using the Android Activity Result API.

**Returns:** `Boolean` - `true` if permission is already granted, `false` if permission request was launched.

### checkARCoreAndProceed()

Checks ARCore availability and installation status:

* If ARCore is installed, proceeds to start AR session
* If ARCore needs installation, requests installation
* If ARCore is not supported, shows error message

### startARSession()

Launches either `MultiSetLocalizationActivity` or `ObjectTrackingActivity` based on the pending action:

```kotlin
// Localization
val intent = Intent(this, MultiSetLocalizationActivity::class.java)
intent.putExtra(
    MultiSetLocalizationActivity.EXTRA_LOCALIZATION_MODE,
    (pendingLocalizationType ?: LocalizationMode.MULTI_FRAME).name
)
startActivity(intent)

// Object Tracking
val intent = Intent(this, ObjectTrackingActivity::class.java)
intent.putExtra(ObjectTrackingActivity.EXTRA_OBJECT_CODES, objectCodes)
startActivity(intent)
```

***

## Callbacks (MultiSetCallback Interface)

### onSDKReady()

Called when the SDK has been initialized and is beginning authentication.

```kotlin
override fun onSDKReady() {
    runOnUiThread {
        binding.authButton.text = getString(R.string.authenticating)
    }
}
```

### onAuthenticationSuccess()

Called when authentication with the MultiSet backend is successful. Enables the Localization and Object Tracking buttons and updates the auth button to show a green "Authenticated" state.

```kotlin
override fun onAuthenticationSuccess() {
    runOnUiThread {
        binding.authButton.text = getString(R.string.authenticated)
        binding.authButton.isEnabled = false
        binding.authButton.backgroundTintList = ColorStateList.valueOf(
            ContextCompat.getColor(this, R.color.success)
        )
        binding.localizationButton.isEnabled = true
        binding.objectTrackingButton.isEnabled = true
    }
}
```

### onAuthenticationFailure(error: String)

Called when authentication fails.

| Parameter | Type     | Description                                 |
| --------- | -------- | ------------------------------------------- |
| `error`   | `String` | Error message describing the failure reason |

```kotlin
override fun onAuthenticationFailure(error: String) {
    runOnUiThread {
        binding.statusText.text = "Authentication Failed"
        binding.authButton.isEnabled = true
        showToast("Authentication failed: $error")
    }
}
```

### onLocalizationSuccess(result: LocalizationResult)

Called when localization succeeds. The result can be logged or used by the host application.

| Parameter | Type                 | Description                                                                                     |
| --------- | -------------------- | ----------------------------------------------------------------------------------------------- |
| `result`  | `LocalizationResult` | Contains map code, map codes list, position, rotation, confidence, and optional geo-coordinates |

```kotlin
override fun onLocalizationSuccess(result: LocalizationResult) {
    Log.d(TAG, "Localization success - mapCode: ${result.mapCode}, " +
            "mapCodes: ${result.mapCodes}, " +
            "position: [${result.position.joinToString()}], " +
            "rotation: [${result.rotation.joinToString()}], " +
            "confidence: ${result.confidence}")
}
```

### onLocalizationFailure(error: String)

Called when localization fails. In `MainActivity`, this is handled by the AR activity.

| Parameter | Type     | Description                                 |
| --------- | -------- | ------------------------------------------- |
| `error`   | `String` | Error message describing the failure reason |

### onTrackingStateChanged(state: TrackingState)

Called when AR tracking state changes. Handled internally by the AR activities.

| Parameter | Type            | Description                                        |
| --------- | --------------- | -------------------------------------------------- |
| `state`   | `TrackingState` | Current tracking state (TRACKING, PAUSED, STOPPED) |

### onObjectTrackingSuccess(result: ObjectTrackingResult)

Called when an object is successfully tracked. Forwarded from `ObjectTrackingActivity` via `MultiSetSDK.getCallback()`.

| Parameter | Type                   | Description                                     |
| --------- | ---------------------- | ----------------------------------------------- |
| `result`  | `ObjectTrackingResult` | Contains object code, pose data, and confidence |

```kotlin
override fun onObjectTrackingSuccess(result: ObjectTrackingResult) {
    Log.d(TAG, "Object tracking success - objectCode: ${result.objectCode}, " +
            "position: [${result.position.joinToString()}], " +
            "confidence: ${result.confidence}")
}
```

### onObjectTrackingFailure(error: String)

Called when object tracking fails.

| Parameter | Type     | Description                                 |
| --------- | -------- | ------------------------------------------- |
| `error`   | `String` | Error message describing the failure reason |

```kotlin
override fun onObjectTrackingFailure(error: String) {
    Log.d(TAG, "Object tracking failure: $error")
}
```

***

## LocalizationResult

| Property         | Type              | Description                                      |
| ---------------- | ----------------- | ------------------------------------------------ |
| `mapCode`        | `String`          | The code of the map where localization succeeded |
| `mapCodes`       | `List<String>`    | All map codes returned by the localization API   |
| `position`       | `FloatArray`      | XYZ position coordinates                         |
| `rotation`       | `FloatArray`      | XYZW quaternion rotation                         |
| `confidence`     | `Float?`          | Confidence score of the localization (0.0 - 1.0) |
| `geoCoordinates` | `GeoCoordinates?` | Optional geographic coordinates                  |

***

## TrackingState

| Value      | Description                       |
| ---------- | --------------------------------- |
| `TRACKING` | AR tracking is working normally   |
| `PAUSED`   | AR tracking is temporarily paused |
| `STOPPED`  | AR tracking has stopped           |

***

## Usage Example

```kotlin
class MainActivity : AppCompatActivity(), MultiSetCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize SDK
        val config = MultiSetConfig.Builder(
            BuildConfig.MULTISET_CLIENT_ID,
            BuildConfig.MULTISET_CLIENT_SECRET
        )
        .mapCode(BuildConfig.MULTISET_MAP_CODE)
        .enableMeshVisualization(true)
        .backgroundLocalization(true)
        .build()

        MultiSetSDK.initialize(this, config, this)
    }

    override fun onAuthenticationSuccess() {
        // Enable localization and object tracking buttons in the UI
    }

    // Launch localization
    fun launchLocalization(mode: LocalizationMode) {
        val intent = Intent(this, MultiSetLocalizationActivity::class.java)
        intent.putExtra(MultiSetLocalizationActivity.EXTRA_LOCALIZATION_MODE, mode.name)
        startActivity(intent)
    }

    // Launch object tracking
    fun launchObjectTracking() {
        val objectCodes = BuildConfig.MULTISET_OBJECT_CODES
            .split(",").map { it.trim() }.filter { it.isNotEmpty() }.toTypedArray()

        ObjectTrackingConfig.objectCodes = objectCodes
        ObjectTrackingConfig.validate()

        val intent = Intent(this, ObjectTrackingActivity::class.java)
        intent.putExtra(ObjectTrackingActivity.EXTRA_OBJECT_CODES, objectCodes)
        startActivity(intent)
    }

    override fun onLocalizationSuccess(result: LocalizationResult) {
        Log.d("MainActivity", "Localized at mapCode: ${result.mapCode}")
    }

    override fun onObjectTrackingSuccess(result: ObjectTrackingResult) {
        Log.d("MainActivity", "Tracked object: ${result.objectCode}")
    }

    override fun onObjectTrackingFailure(error: String) {
        Log.e("MainActivity", "Tracking failed: $error")
    }

    override fun onAuthenticationFailure(error: String) {
        Toast.makeText(this, "Auth failed: $error", Toast.LENGTH_SHORT).show()
    }

    // ... other callback implementations
}
```

***

## Related

* [MultiSetLocalizationActivity](/multiset/native-support/android-native/sample-activities/multisetlocalizationactivity.md)
* [ObjectTrackingActivity](/multiset/native-support/android-native/sample-activities/objecttrackingactivity.md)
* [LocalizationConfig](/multiset/native-support/android-native/api-reference/localizationconfig.md)
* [ObjectTrackingConfig](/multiset/native-support/android-native/api-reference/objecttrackingconfig.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://multiset.gitbook.io/multiset/native-support/android-native/sample-activities/mainactivity.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
