AppInspect 0.7.0
On this page
Getting started

Opening the inspector

The inspector is a full screen inside your app, and there are six ways to reach it. Which one matters more than it sounds: a tester who cannot open the tool will not use it, and a gesture that fires by accident during a demo is worse than no gesture at all.

The ways in

Entry pointTurned on byBest for
Shake the device shakeToOpenEnabled Testers on physical devices. Nothing to find on screen.
Launcher shortcut launcherShortcutEnabled Opening the inspector before the app itself, or on an emulator where shaking is awkward.
Long press a view autoOpenOnLongPressTrigger plus a trigger you attach A deliberate, discoverable gesture on a screen you choose — a logo, a version label.
Tap a network notification networkNotificationsEnabled Jumping straight to the call you just watched go past. See Network notifications.
AppInspect.open(context) Always available Wiring the inspector into a debug menu you already have.
AppInspectActivity Always available Starting the activity yourself when you need control over the intent.

Shake to open

Shake detection watches the total accelerometer magnitude, gravity included — the same approach as Square's Seismic. At rest that reads about 1 g, and ordinary handling such as picking the phone up stays around 1.0–1.5 g, so only a deliberate shake crosses the default threshold of 2.7 g.

A single spike is not enough: the threshold has to be crossed by at least two samples inside a 500 ms window. Cheaper or older accelerometers occasionally report one wild value, and that lone sample is ignored, while a real shake produces several.

AppInspectEntryPoints
AppInspectEntryPoints(
    shakeToOpenEnabled = true,
    shakeThresholdGravity = 2.7f,   // total g-force, gravity included
    shakeCooldownMillis = 1_500L,   // ignore repeats for this long after opening
)

Lower the threshold to about 2.3 g if your testers report that shaking never works; raise it if the inspector keeps appearing in someone's pocket. Values below roughly 1.5 g are floored, because at that point normal movement would trigger it constantly.

Launcher shortcut

With launcherShortcutEnabled, AppInspect registers a dynamic shortcut on your app icon. Long-press the icon on the home screen and the inspector is one tap away, without launching into the app first. This is usually the easiest entry point to explain to a non-developer, and the most reliable on an emulator.

Long press a view

A long-press trigger is the option to reach for when you want the gesture to be predictable. You attach it to a specific view or composable — a version number in the settings screen is a common choice — so nobody opens the inspector by accident, and anyone who knows the trick can open it instantly.

Views
val handle = AppInspect.attachLongPressTrigger(versionLabel)

// Later, if the view outlives the trigger
handle.unregister()
Compose
val handle = rememberAppInspectLongPressTriggerHandle()

Text(
    text = "v${BuildConfig.VERSION_NAME}",
    modifier = Modifier.appInspectLongPressTrigger(handle),
)

An accepted long press opens the inspector automatically as long as autoOpenOnLongPressTrigger is on. Turn that off and the trigger still reports the gesture, which lets you show your own confirmation first.

From your own debug menu

If your app already has an internal debug screen, add one row to it:

Anywhere with a Context
AppInspect.open(context)

The call is refused when the library is disabled, so it is safe to leave in place — but remember that AppInspect.open() does not exist in appinspect-no-op, so keep the call in a debug-only source set. The install page explains which parts of the API are safe in shared code.

It opens in its own Recents card

By default the inspector opens in a separate task. That means it appears as its own card in Recents, next to your app, and the two can sit side by side in split-screen — genuinely useful when you want to watch calls arrive while tapping through a flow.

It still runs in your app's process, so nothing is lost by doing this: a task is a back-stack and Recents grouping, not a separate process. Every panel works exactly the same.

If you would rather it appeared stacked on top of the current screen, set openInSeparateTask = false. No manifest change is needed either way — the activity and its task affinity are merged in from the library's manifest.

Moving around once it is open

Five panels sit on the bottom bar: Network, Mocks, Storage, Work and Crashes. Tap them or swipe left and right across the content — the bar and the swipe stay in sync.

Runtime is deliberately not on the bottom bar. It is reference data you consult occasionally rather than a workflow you switch between, so it lives behind a circular icon button in the top bar, just left of the close button, badged with the number of sections it has. Tapping it opens Runtime as its own full screen.

Any panel can hand an oversized value to the shared value viewer — a response body, a preference holding a large JSON blob, a database cell.

Hiding entry points

Every entry point can be switched off independently, which is how you hand a build to a wider audience without advertising that the inspector is there. The configuration reference lists all of them in one place.