Storage
Three kinds of on-device storage in one panel: SharedPreferences, Jetpack DataStore, and SQLite or Room databases. It answers the question a network log cannot — the API returned the right thing, so what did the app actually keep?
SharedPreferences
AppInspect discovers the preference files your app has, lists their keys and values in order, and lets you change them. Tap a row to open the editor, which handles each value by its type and offers Copy, Paste and Clear.
Search runs across file names, keys and values, and results from every file appear in one list, a single tap from the editor. Matching is debounced and runs off the main thread, so typing stays smooth even when a preference holds a several-hundred-kilobyte JSON blob — which, in practice, plenty of them do.
A value too large to lay out in a text field — above roughly 8,000 characters — opens as a bounded preview with an Open value button into the value viewer. Copy, Paste and Clear still apply to the whole value, and nothing stored is ever truncated.
Encrypted preferences
EncryptedSharedPreferences files are detected automatically and
decrypted for viewing, using your app's own on-device Keystore key. Decryption never
leaves the device. These files are marked with a lock badge and are deliberately
read only — they can never be edited or deleted from the
inspector, so an encrypted store cannot be corrupted by a stray tap.
Jetpack DataStore
DataStore Preferences files (.preferences_pb) are read only, and are
parsed by a small protobuf reader built into the library. That means AppInspect does
not need a DataStore dependency of its own, and it will not drag one into your build.
Decoded entries are shown with a type label — STRING,
INT, LONG, FLOAT, DOUBLE,
BOOLEAN, STRING_SET, BYTES — and search
works across file names, keys and values, debounced and off the main thread as in
Preferences.
SQLite and Room
Databases are discovered from your app's own storage. AppInspect's internal database is excluded from the list, as are its internal preference files, so what you see is your app's data and nothing else.
- Schema browsing — tables, entities and column types.
- Paged row inspection, with structured editing of a row's fields.
- A SQL console for the queries a browser cannot express. Mutating statements require an explicit action rather than running on a stray Enter, and the console can be switched off entirely.
Each area has its own empty-state card — no databases, no table selected yet, a file with nothing in it — rather than a blank screen you have to interpret.
Editing writes to your app's real storage
This is worth stating clearly: preference and database edits are applied directly to the host app's on-device storage. There is no sandbox and no undo. Setting a preference to force a state is genuinely useful — skipping onboarding, expiring a token, pretending a feature flag is on — and it is a real write.
For builds that go to a wider audience, the write side can be removed while keeping everything readable:
AppInspectPowerTools(
allowSharedPreferencesEditing = false,
allowDatabaseEditing = false,
allowSqlConsole = false,
)
Hiding the panel altogether is AppInspectPanels(storageEnabled = false).
Both are covered on the
configuration reference.
Storage contents are shown as they are, which in a debug build includes tokens,
session data and anything else your app persists. That is intended for developer
tooling — the security model explains the
boundary, and showRawSensitiveValues = false masks configured
sensitive values.