# What Technologies Are Used in the Google Timeline Visualizer Android App?

> Explore the technologies powering the Google Timeline Visualizer Android app. Discover Kotlin, Jetpack, AndroidX Media3, and more for efficient video visualization.

- Repository: [mahlernim/google-timeline-visualizer](https://github.com/mahlernim/google-timeline-visualizer)
- Tags: internals
- Published: 2026-08-23

---

**The Google Timeline Visualizer Android app is built with Kotlin, Android Jetpack libraries, and AndroidX Media3 for video processing, targeting compileSdk 36 with minSdk 26.**

This open-source Android application, hosted at [mahlernim/google-timeline-visualizer](https://github.com/mahlernim/google-timeline-visualizer), ingests Google Takeout JSON exports and transforms location history into interactive timeline visualizations and shareable MP4 videos. Understanding the technology stack behind the Google Timeline Visualizer Android app reveals how modern Android architecture combines declarative UI patterns with powerful media pipelines.

## Language and Build System

The Google Timeline Visualizer Android codebase is **100% Kotlin**. All source files use the `*.kt` extension, from UI components to background services.

Build configuration lives in [`app/build.gradle.kts`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/build.gradle.kts), which uses the **Gradle Kotlin DSL** rather than Groovy. Key SDK constraints include:

- **compileSdk**: 36
- **minSdk**: 26 (Android 8.0+)
- **targetSdk**: aligned with compileSdk

The build file enables **ViewBinding** (`buildFeatures.viewBinding = true`) for type-safe view access and eliminates findViewById boilerplate.

## Core AndroidX and Jetpack Components

### UI and Theming

- **AppCompat 1.7.1** (`androidx.appcompat:appcompat`) — backward-compatible Activity and theming support
- **Material Design Components 1.13.0** (`com.google.android.material:material`) — Material3 dynamic color and component library

### Architecture Components

- **Lifecycle-aware ViewModel 2.10.0** (`androidx.lifecycle:lifecycle-viewmodel-ktx`) — survives configuration changes, used in [`MainActivity.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/MainActivity.kt), [`SettingsViewModel.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/SettingsViewModel.kt)
- **Activity Result Contracts** (`androidx.activity`) — modern permission and activity result handling, imported in [`MainActivity.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/MainActivity.kt) as `import androidx.activity.result.contract.ActivityResultContracts`
- **AppLocale support** (`androidx.appcompat`) — dynamic language switching

The UI layer combines these in files like [[`TimelineView.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/TimelineView.kt)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/java/dev/mahlernim/timelinevisualizer/ui/TimelineView.kt) and [[`MainActivity.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/MainActivity.kt)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/java/dev/mahlernim/timelinevisualizer/MainActivity.kt).

## Asynchronous Processing with Kotlin Coroutines

All background work—parsing large JSON files, generating video frames, writing MP4 files—runs on **Kotlin Coroutines 1.10.2** (`kotlinx-coroutines-android`).

This appears in ViewModels through `viewModelScope.launch(Dispatchers.IO)` and in the export pipeline through structured concurrency.

## Data Parsing with Gson

Google Takeout exports arrive as dense JSON. The app uses **Gson 2.13.2** (`com.google.code.gson:gson`) for deserialization into Kotlin data classes. The parsing logic resides in [[`TimelineParser.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/TimelineParser.kt)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/java/dev/mahlernim/timelinevisualizer/data/TimelineParser.kt).

Example pattern from the codebase:

```kotlin
class TimelineViewModel : ViewModel() {
    private val _timeline = MutableLiveData<Timeline>()
    val timeline: LiveData<Timeline> = _timeline

    fun load(json: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val parsed = Gson().fromJson(json, Timeline::class.java)
            _timeline.postValue(parsed)
        }
    }
}

```

## Video Pipeline: AndroidX Media3

The Google Timeline Visualizer Android app's signature feature—exporting location timelines as MP4 videos—depends entirely on **AndroidX Media3 1.11.0**. Three modules handle different responsibilities:

| Media3 Module | Purpose | Implementation Location |
|-------------|---------|------------------------|
| `media3-exoplayer` | In-app video preview/playback | [`MainActivity.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/MainActivity.kt) |
| `media3-muxer` | MP4 file generation | [`Mp4Exporter.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/Mp4Exporter.kt) |
| `media3-ui` | Player controls and surface | Layout XML with `PlayerView` |

### ExoPlayer Integration

Playback setup in [`MainActivity.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/MainActivity.kt) (simplified):

```kotlin
// MainActivity.kt – player initialization
private val player = ExoPlayer.Builder(this).build().apply {
    setMediaItem(MediaItem.fromUri(videoUri))
    prepare()
    playWhenReady = true
}
binding.playerView.player = player

```

### MP4 Export with Muxer

The [[`Mp4Exporter.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/Mp4Exporter.kt)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/java/dev/mahlernim/timelinevisualizer/export/Mp4Exporter.kt) file contains the video encoding logic:

```kotlin
@OptIn(UnstableApi::class)
fun exportMp4(frames: List<Frame>, output: File) {
    val muxer = Mp4Muxer(
        FileOutputStream(output).channel, 
        Mp4Muxer.OutputMode.MUXER_OUTPUT_MODE_AUTO
    )
    val track = muxer.addVideoTrack(
        MediaFormatUtil.createVideoFormat(MIME_VIDEO_AVC, width, height, 30_000L)
    )
    frames.forEach { frame ->
        muxer.writeSampleData(
            track, 
            frame.buffer, 
            MuxerBufferInfo(frame.timeUs, frame.size, false)
        )
    }
    muxer.close()
}

```

The [[`VideoExportService.kt`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/VideoExportService.kt)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/java/dev/mahlernim/timelinevisualizer/export/VideoExportService.kt) wraps this in a foreground service with notification support for long-running exports.

## Storage, Preferences, and Permissions

### Simple Preferences

Rather than a full dependency injection framework, the app uses `androidx.core.content.edit` extension functions for lightweight `SharedPreferences` operations, visible across multiple `*Preferences.kt` files.

### Required Permissions

The [[`AndroidManifest.xml`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/AndroidManifest.xml)](https://github.com/mahlernim/google-timeline-visualizer/blob/main/app/src/main/AndroidManifest.xml) declares:
- `INTERNET` — for map tile loading
- `FOREGROUND_SERVICE` and `FOREGROUND_SERVICE_MEDIA_PLAYBACK` — for video export
- Notification permissions — for export progress updates

## Testing Infrastructure

Unit tests rely on:
- **JUnit 4.13.2** — test runner
- **Robolectric** — Android framework simulation without emulator
- **AndroidX Test Core 1.7.0** — ActivityScenario and core test utilities

## Summary

- **Language**: Kotlin throughout, with Gradle Kotlin DSL build configuration
- **UI Framework**: Jetpack ViewBinding, Material3, Lifecycle ViewModel, Activity Result Contracts
- **Concurrency**: Kotlin Coroutines for all async operations
- **Serialization**: Gson for Google Takeout JSON parsing
- **Media Stack**: AndroidX Media3 (ExoPlayer, Muxer, UI components) for playback and MP4 export
- **Architecture**: MVVM pattern with ViewModel and LiveData
- **Services**: Foreground service with notifications for background video rendering

## Frequently Asked Questions

### What is the minimum Android version required for Google Timeline Visualizer?

The app requires **Android 8.0 (API 26)** or higher, as specified by `minSdk 26` in `app/build.gradle.kts`. This covers approximately 95%+ of active Android devices globally.

### Why does the app use Media3 instead of older media libraries?

Media3 consolidates ExoPlayer, media session APIs, and media extraction tools into a single maintained library. The Google Timeline Visualizer Android app specifically needs Media3's **Mp4Muxer** class—unavailable in legacy support libraries—for frame-accurate video generation without external ffmpeg dependencies.

### Is the Google Timeline Visualizer Android app written in Java or Kotlin?

The codebase is **100% Kotlin**. Every source file in `app/src/main/java/` uses the `.kt` extension, including Activities, ViewModels, Services, and data classes. This aligns with Google's modern Android development recommendations.

### How does the app handle large Google Takeout JSON files without freezing the UI?

JSON parsing executes on the **IO dispatcher** via `viewModelScope.launch(Dispatchers.IO)`, keeping the main thread responsive. The parsed `Timeline` object posts to `LiveData`, which the UI observes on the main thread—a standard coroutine pattern for file I/O in Android.