Android Example
A Kotlin Android application that renders a MapLibre GL Native vector tile map and adds places search. Uses a custom OkHttp interceptor for tile authentication.
Prerequisites
- Android Studio Ladybug (2024.2+)
- Android API 24+ (Android 7.0) device or emulator
- A Geog API key (create one in the console)
Quick Start
git clone https://github.com/geogdev/examples.git
Open examples/mobile/android-maplibre in Android Studio. Add your API key to local.properties:
GEOG_API_KEY=your-api-key-here
Click Sync Now when prompted for Gradle sync, then run the app.
Project Structure
| File | Description |
|---|---|
local.properties | API key storage (git-ignored) — injected via Gradle buildConfigField |
app/build.gradle.kts | Module config — reads API key from local.properties into BuildConfig |
app/src/main/java/.../api/GeogService.kt | API client — OkHttp-based authentication and places search |
app/src/main/java/.../MapFragment.kt | Fragment — MapLibre map with programmatic style and OkHttp auth interceptor |
app/src/main/java/.../PlacesSearchFragment.kt | Fragment — search UI, results list, and marker management |
app/src/main/java/.../api/Place.kt | @Serializable data model for search results |
How It Works
Bundle / Application ID Authentication
Mobile apps authenticate using application ID restrictions instead of token exchange. When you create an API token in the console, you can restrict it to specific Android application IDs (e.g., com.yourcompany.yourapp). The app sends its application ID via the X-App-Bundle-Id header, and the Geog API rejects calls whose header doesn't match an allowed identifier.
Application ID restrictions reduce casual abuse — an extracted key won't work from an app with a different application ID — but the header is client-supplied and can be spoofed. For production apps with high-value keys, consider proxying API calls through your own backend so the key is never shipped in the APK.
To configure application ID restrictions:
- Go to Tokens in the console
- Edit your token's settings
- Add your app's application ID under Allowed Bundle IDs
API Key Configuration
The API key is stored in local.properties (git-ignored) and injected into the app at build time through Gradle:
// app/build.gradle.kts
android {
defaultConfig {
buildConfigField(
"String",
"GEOG_API_KEY",
"\"${localProperties["GEOG_API_KEY"]}\""
)
}
}
Access it in code as BuildConfig.GEOG_API_KEY.
Custom OkHttp Interceptor
MapLibre GL Native for Android uses OkHttp under the hood. A custom interceptor attaches the API key and application ID to all Geog API requests (tiles and places):
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val request = chain.request()
if (request.url.host == "api.geog.dev") {
chain.proceed(
request.newBuilder()
.header("Authorization", "Bearer ${BuildConfig.GEOG_API_KEY}")
.header("X-App-Bundle-Id", BuildConfig.APPLICATION_ID)
.build()
)
} else {
chain.proceed(request)
}
}
.build()
HttpRequestUtil.setOkHttpClient(client)
Coroutines
All API calls are suspend functions and run within lifecycleScope for structured concurrency.
Full Source
github.com/geogdev/examples/tree/main/mobile/android-maplibre
See Also
- Examples Overview — All examples (this example uses direct API-key auth with bundle ID restrictions)
- Vector Tiles API — Tile endpoint reference
- Places API — Search endpoint reference (preview — will change)
- Styles & Sprites — Hosted themes, sprites, and npm packages