# Android > https://docs.errora.org/en/platforms/android Errora works with the official [Sentry Android SDK](https://docs.sentry.io/platforms/android/) and the Sentry Android Gradle plugin, unchanged. The SDK reports Java/Kotlin crashes, NDK (native) crashes and ANRs; the Gradle plugin uploads the files Errora needs to turn an obfuscated or native stack back into your code. Create the project with the **Android** platform so the UI shows the right snippets. ## Install The recommended route is the Gradle plugin, which adds the SDK for you and uploads mappings and symbols on every release build: ```kotlin // app/build.gradle.kts plugins { id("com.android.application") id("io.sentry.android.gradle") version "5.+" // pin an exact version in real builds } ``` Without the plugin, add the SDK yourself (it bundles NDK crash reporting): ```kotlin dependencies { implementation("io.sentry:sentry-android:8.+") } ``` ## Initialize ### Option 1 — the manifest The SDK initializes itself from `AndroidManifest.xml`: ```xml ``` ### Option 2 — in code Turn auto-init off in the manifest, then call `SentryAndroid.init` from your `Application`: ```xml ``` ```kotlin import io.sentry.android.core.SentryAndroid class App : Application() { override fun onCreate() { super.onCreate() SentryAndroid.init(this) { options -> options.dsn = "https://@/" options.environment = "production" options.tracesSampleRate = 0.2 // tracing options.profilesSampleRate = 1.0 // profiling (of sampled transactions) options.isAttachScreenshot = true // screenshot on error options.isAttachViewHierarchy = true // view hierarchy on error options.sessionReplay.onErrorSampleRate = 1.0 options.sessionReplay.sessionSampleRate = 0.1 options.isAnrEnabled = true // default: on options.isEnableAutoSessionTracking = true // default: on — feeds release health } } } ``` ## Options worth enabling | Option | What you get in Errora | | --- | --- | | `tracesSampleRate` | [Performance](/en/products/performance): app start, activity and fragment transactions, HTTP spans | | `profilesSampleRate` | [Profiling](/en/products/profiling) of sampled transactions (ART method traces) | | `isAttachScreenshot` | A screenshot stored with each error, previewed on the issue page | | `isAttachViewHierarchy` | The view tree at the moment of the error, rendered as a tree on the issue page | | `sessionReplay.*SampleRate` | [Mobile session replay](/en/products/session-replay#mobile-replays) | | `isAnrEnabled` | ANRs arrive as ordinary errors and group/alert like any issue; they also feed the ANR rate | | `isEnableAutoSessionTracking` | Sessions for [release health](/en/products/release-health) — on by default | You don't need to set `release`: the SDK sets it to `@+` automatically, and that is the string release health and debug-file matching key on. Screenshots and view hierarchies are [attachments](/en/products/issues#attachments): they are stored with their event, follow the organization's [data retention](/en/account/retention), and are dropped with the event when it is sampled out or spike-limited. ## Upload ProGuard/R8 mappings and NDK symbols A minified release build reports frames like `a.b.c.d(SourceFile)`, and native crashes report bare addresses. Errora deobfuscates and symbolicates them **before grouping** using the files you upload — see [Debug files](/en/products/debug-files) for how matching works. Point the Gradle plugin at Errora: ```kotlin // app/build.gradle.kts sentry { url.set("https://") org.set("") projectName.set("") authToken.set(System.getenv("SENTRY_AUTH_TOKEN")) // errora_pat_… includeProguardMapping.set(true) // ProGuard/R8 mapping.txt autoUploadProguardMapping.set(true) // upload it as part of the build uploadNativeSymbols.set(true) // NDK .so debug symbols includeNativeSources.set(false) telemetry.set(false) // don't report build telemetry to sentry.io } ``` - `authToken` is an Errora [personal access token](/en/account/tokens) (`errora_pat_…`) whose owner is a **member** (or higher) of the organization. Keep it in your CI's secret store, not in the repository. - `org` is the organization slug from your dashboard URL (`/organizations//…`); `projectName` is the project's slug. - The plugin also reads `sentry.properties` and the `SENTRY_URL`, `SENTRY_ORG`, `SENTRY_PROJECT` and `SENTRY_AUTH_TOKEN` environment variables, if you'd rather keep the block empty. The plugin stamps every build with a ProGuard UUID that the SDK reports, so each crash is deobfuscated with the mapping of the exact build that produced it. You can check what arrived under **Settings → Debug files**. ### Without the Gradle plugin Use `sentry-cli` with the same four settings: ```bash export SENTRY_URL=https:// export SENTRY_AUTH_TOKEN=errora_pat_… export SENTRY_ORG= export SENTRY_PROJECT= sentry-cli upload-proguard --uuid app/build/outputs/mapping/release/mapping.txt sentry-cli debug-files upload app/build/intermediates/merged_native_libs/release/ ``` The `--uuid` must be the ProGuard UUID the app reports — which is why the plugin is the easier path. ## Verify Build a **release** variant (so minification and the upload both run), then: ```kotlin Sentry.captureException(RuntimeException("Errora smoke test")) // or crash for real: throw RuntimeException("Errora crash test") ``` An unhandled crash is sent the next time the app starts. Open the issue: frames should show real class and method names with line numbers. If a frame is still obfuscated, the issue page says which mapping (debug id) is missing. ## Troubleshooting | Symptom | Cause / fix | | --- | --- | | Frames still look like `a.b.c` | The mapping wasn't uploaded for that build — check the Gradle output and **Debug files** | | Native frames show only addresses | Upload NDK symbols (`uploadNativeSymbols`), from the **unstripped** `.so` files | | Upload fails with `401` | Wrong or revoked token, or `url` still points to sentry.io | | Upload fails with `403` | The token's owner isn't a member of that organization | | No release health data | Auto session tracking was turned off | | No crash after `throw` | Crashes are sent on the **next** launch — reopen the app |