Skip to main content

Android

Errora works with the official Sentry Android SDK 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:

// 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):

dependencies {
implementation("io.sentry:sentry-android:8.+")
}

Initialize​

Option 1 — the manifest​

The SDK initializes itself from AndroidManifest.xml:

<application>
<meta-data android:name="io.sentry.dsn"
android:value="https://<public_key>@<your-errora-host>/<project_id>" />
<meta-data android:name="io.sentry.traces.sample-rate" android:value="0.2" />
<meta-data android:name="io.sentry.attach-screenshot" android:value="true" />
<meta-data android:name="io.sentry.attach-view-hierarchy" android:value="true" />
<meta-data android:name="io.sentry.session-replay.on-error-sample-rate" android:value="1.0" />
<meta-data android:name="io.sentry.session-replay.session-sample-rate" android:value="0.1" />
</application>

Option 2 — in code​

Turn auto-init off in the manifest, then call SentryAndroid.init from your Application:

<meta-data android:name="io.sentry.auto-init" android:value="false" />
import io.sentry.android.core.SentryAndroid

class App : Application() {
override fun onCreate() {
super.onCreate()
SentryAndroid.init(this) { options ->
options.dsn = "https://<public_key>@<your-errora-host>/<project_id>"
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​

OptionWhat you get in Errora
tracesSampleRatePerformance: app start, activity and fragment transactions, HTTP spans
profilesSampleRateProfiling of sampled transactions (ART method traces)
isAttachScreenshotA screenshot stored with each error, previewed on the issue page
isAttachViewHierarchyThe view tree at the moment of the error, rendered as a tree on the issue page
sessionReplay.*SampleRateMobile session replay
isAnrEnabledANRs arrive as ordinary errors and group/alert like any issue; they also feed the ANR rate
isEnableAutoSessionTrackingSessions for release health — on by default

You don't need to set release: the SDK sets it to <package>@<versionName>+<versionCode> automatically, and that is the string release health and debug-file matching key on.

Screenshots and view hierarchies are attachments: they are stored with their event, follow the organization's data 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 for how matching works.

Point the Gradle plugin at Errora:

// app/build.gradle.kts
sentry {
url.set("https://<your-errora-host>")
org.set("<organization-slug>")
projectName.set("<project-slug>")
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 (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/<slug>/…); 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:

export SENTRY_URL=https://<your-errora-host>
export SENTRY_AUTH_TOKEN=errora_pat_…
export SENTRY_ORG=<organization-slug>
export SENTRY_PROJECT=<project-slug>

sentry-cli upload-proguard --uuid <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:

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​

SymptomCause / fix
Frames still look like a.b.cThe mapping wasn't uploaded for that build — check the Gradle output and Debug files
Native frames show only addressesUpload NDK symbols (uploadNativeSymbols), from the unstripped .so files
Upload fails with 401Wrong or revoked token, or url still points to sentry.io
Upload fails with 403The token's owner isn't a member of that organization
No release health dataAuto session tracking was turned off
No crash after throwCrashes are sent on the next launch — reopen the app