# Getting Started

Use this guide to set up the Android application for Offline Navigation by adding the SDK, configuring Android permissions, applying runtime behavior, and initializing Maps and `NBNavigation` in the correct order.

## Install the SDK

Add Navigation **Android SDK 3.0.1** to the application module. The AAR transitively supplies the verified Maps SDK version used by offline navigation. Do not force a different Maps SDK version unless NextBillion.ai Support explicitly instructs you to do so.

### Kotlin DSL

```kotlin
// settings.gradle.kts
import org.gradle.api.initialization.resolve.RepositoriesMode

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

// app/build.gradle.kts
dependencies {
    implementation("ai.nextbillion:nb-navigation-android:3.0.1")

// Sample application dependency only
    implementation("androidx.activity:activity-ktx:1.9.3")
}
```

### Groovy DSL

```bash
// settings.gradle
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

// app/build.gradle
dependencies {
    implementation "ai.nextbillion:nb-navigation-android:3.0.1"
    implementation "androidx.activity:activity-ktx:1.9.3"
}
```

If NextBillion.ai provides your organization with a private Maven repository, add that repository alongside _mavenCentral()_ using the URL and read-only credentials supplied for your deployment. Store those credentials in the user-level Gradle properties file or CI secrets. Application consumers do not need the `centralUsername` or `centralToken` publishing credentials used by the SDK release pipeline.

## Configure permissions

Declare only the permissions required by the features that the application uses. Catalog synchronization and regional downloads require network access but do not require location permission. Continuous turn-by-turn navigation normally uses location and a location-type foreground service.

### Manifest Declarations

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Required for catalog sync, data download, and online routing. -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Required only when the app uses device location or starts navigation. -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Required for continuous navigation in a foreground service. -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

    <!-- Runtime permission on Android 13 / API 33 and later. -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
</manifest>
```

### Permission Requirements

| Permission | Required when | Runtime handling |
| --- | --- | --- |
| `INTERNET` | Catalog sync, regional download, online routing | Manifest only |
| `ACCESS_NETWORK_STATE` | TTL refresh, network policy, SMART routing | Manifest only |
| `COARSE / FINE LOCATION` | Current-position region search or navigation | Request in context; precise navigation normally needs `FINE` |
| `FOREGROUND_SERVICE` | A foreground navigation service is used | Manifest only |
| `FOREGROUND_SERVICE_LOCATION` | Location foreground service on API 34+ | Manifest; location runtime permission must already be granted |
| `POST_NOTIFICATIONS` | Navigation notifications on API 33+ | Request at runtime before the navigation flow when possible |

### Runtime Rules

-   Request location permission only when the user selects a feature that needs location. Downloading offline data by `regionId` does not require location permission.

-   On **Android 12** and later, request `COARSE` and `FINE` together when the navigation experience needs precise location. Continue with reduced functionality or stop the flow if the user grants only an approximate location.

-   On **Android 13** and later, `POST_NOTIFICATIONS` is not required to start a foreground service, but a denied permission prevents normal display of the navigation notification in the notification drawer.

-   Starting with **Android 14 (API level 34)**, applications running a location-based foreground service must declare the `FOREGROUND_SERVICE_LOCATION` permission in their manifest. Users must also turn on system location services and grant either `ACCESS_COARSE_LOCATION` or `ACCESS_FINE_LOCATION` before navigation starts. Note that precise turn-by-turn guidance typically requires `ACCESS_FINE_LOCATION`. Since location access is treated as a "while-in-use" permission, initiate the navigation foreground service while an “Activity” is actively visible on screen. `ACCESS_BACKGROUND_LOCATION` is not necessary for standard visible starts, and is only needed if your application explicitly launches or retrieves location updates from the background where platform policies permit.

-   The Navigation AAR declares its navigation service and location foreground-service type. Do not redeclare the SDK service unless a documented manifest override is required.


> _Android references: [notification runtime permission](https://developer.android.com/develop/ui/views/notifications/notification-permission) and [location foreground-service requirements](https://developer.android.com/develop/background-work/services/fgs/service-types#location)._

## Configure runtime behavior

Configure the route mode and download network policy before users start offline routing or region downloads. Offline-capable apps should usually switch from the default online-only behavior to a mode such as `SMART`, then keep the selected download policy consistent when updating runtime configuration.

```kotlin
NBNavigation.setRuntimeConfig(
    RouteMode.SMART,
    NBNavigation.getDownloadNetworkPolicy()
)
```

Runtime configuration applies to the current application process. Reapply the intended route mode and download policy during application startup before opening offline navigation screens.

## Initialize Maps during app startup

Initialize the Maps SDK first in your custom application. If Maps is already initialized, do not initialize it again with a different access key, tile server, or CDN. Please note that offline maps require `NGLTomTom`.

```kotlin
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        val accessKey = getString(R.string.nextbillion_access_key)
        Nextbillion.getInstance(
            this,
            accessKey,
            NGLWellKnownTileServer.NGLTomTom
        )
    }
}
```

```xml
<application
    android:name=".MyApplication"
    ... />
```

## Initialize Offline Navigation

Follow the below steps to initialize offline navigation successfully:

1.  Call _NBNavigation.initialize()_ after _Nextbillion.(@NonNull Context context, @Nullable String apiKey)_ is called.

2.  Initialization is process-wide, consequently, concurrent calls are coalesced into the same operation.

3.  After initialization succeeds, a subsequent _initialize()_ call returns immediately without shutting down or restarting the engine.


Application code should still manage state centrally through an application-scoped Repository or Manager.

```kotlin
fun initializeOfflineNavigation() {
    NBNavigation.initialize(object : NBNavigationTaskCallback<Void> {
        override fun onSuccess(result: Void?) {
            loadRegionCatalog(force = false)
        }

        override fun onError(throwable: Throwable) {
            showOfflineError("Offline initialization failed", throwable)
        }
    })
}
```

`syncRegions()` also protects the default engine with automatic initialization and waits for any initialization already in progress. Production applications should still call `initialize()` explicitly so they can handle errors and readiness before opening the offline screen.

### Callback threading and state handling

Native and network completion callbacks are posted to the main thread. Parameter validation failures and some immediate results may be returned synchronously. Do not assume that a callback will always occur after the current call stack returns.

### Engine shutdown

Do not call _NBNavigation.shutdown()_ when a normal Activity or Fragment is destroyed or when one navigation session ends.

Shut it down only when the process explicitly disables the entire offline capability. Note that a shutdown does not delete data. Call `initialize()` again before subsequent use.

## Recommended call sequence

Use the following recommended call sequence:

1.  Initialize the Maps SDK with the `TomTom` tile server in application.

2.  Call _NBNavigation.initialize()_ to initialize offline navigation.

3.  Read the local catalogs first for immediate display, then synchronize with `AUTO` and refresh the list.

4.  Download the region by `regionId`, and observe `routeNetwork` and `mapTile` progress.

5.  Set _RouteMode_, then continue using _NBNavigation.fetchRoute()_ and the existing navigation screens.
