In the Android operating system, applications encapsulate and share relational data through the ContentProvider abstraction. Whether querying system contacts, media store metadata, calendar entries, or custom application databases, data is accessed via standardized content URIs (e.g., content://...). While developers typically interact with providers programmatically using ContentResolver inside Java or Kotlin code, debugging provider endpoints, verifying URI permissions, and auditing database states during automated testing is streamlined using the Android Debug Bridge (ADB) content command.
Understanding Android Content Providers and URIs
A Content Provider acts as a structured interface between an application’s private SQLite storage and the rest of the Android framework. Rather than exposing raw database files, a provider exposes a secure, IPC-mediated endpoint identified by an authority string and path.
A standard Android content URI follows this structure:
content://com.example.provider/table_name/item_id
When an interaction occurs, the Android framework enforces permissions defined in the provider’s manifest entry (such as readPermission and writePermission). The ADB content tool executes directly inside the Android shell with shell user (UID 2000) or root privileges, allowing developers to execute CRUD (Create, Read, Update, Delete) operations directly against accessible providers from the command line.
Connecting via ADB and Exploring the content Command Syntax
Ensure that your Android device or emulator has USB Debugging enabled and is connected to your workstation. Open a terminal and check connected devices:
adb devices
To inspect the available arguments and operations supported by the content utility, run:
adb shell content
The primary sub-commands supported include:
query: Reads records from a content URI with projection, selection, and sorting arguments.insert: Inserts a new row with designated column values.update: Modifies existing rows matching a selection criteria.delete: Removes rows matching a selection criteria.call: Invokes custom provider methods.
Querying System Providers and Settings
One of the most practical applications of content query is inspecting system settings tables and hardware states that do not have dedicated shell tools.
To query global system settings stored in the system settings provider, run:
adb shell content query --uri content://settings/global
To narrow down the output to a specific setting—such as checking whether ADB Wi-Fi debugging or mobile data is enabled—use the --where clause:
adb shell content query --uri content://settings/global --where "name='mobile_data'"
The output returns the row data structured as key-value pairs:
Row: 0 _id=125, name=mobile_data, value=1
You can similarly query the secure settings table (content://settings/secure) or the user system table (content://settings/system).
Querying the Media Store for Media Files and Documents
The Android MediaStore provider indexes all external images, videos, audio tracks, and download files stored across the device’s shared storage.
To inspect recently captured images using content query, specify the images media URI along with a projection list (--projection) to limit returned columns:
adb shell content query --uri content://media/external/images/media --projection _id:_display_name:mime_type:size --sort "_id DESC"
The output presents tabular file records:
Row: 0 _id=10042, _display_name=IMG_20261107_094512.jpg, mime_type=image/jpeg, size=3451200
Row: 1 _id=10041, _display_name=Screenshot_20261106.png, mime_type=image/png, size=812400
This provides an instant method to verify whether newly generated photos or downloaded PDFs have been indexed into the system media scanner without rebooting the device.
Inserting and Updating Data via ADB content
In addition to reading data, the content utility can insert test records or modify existing entries. Values are passed using the --bind switch, specifying the column name, data type (such as s for string, i for integer, b for boolean), and value.
To insert a test row into a custom application provider:
adb shell content insert --uri content://com.example.todo.provider/tasks --bind title:s:"Review quarterly reports" --bind completed:b:false --bind priority:i:1
To update an existing record (for example, marking the task as completed):
adb shell content update --uri content://com.example.todo.provider/tasks --bind completed:b:true --where "title='Review quarterly reports'"
To delete the test row:
adb shell content delete --uri content://com.example.todo.provider/tasks --where "title='Review quarterly reports'"
Troubleshooting Security Exceptions and Permissions
If running content query returns java.lang.SecurityException: Permission Denial, the targeted provider is protected by permissions not granted to the ADB shell user (UID 2000).
To resolve this during local development:
- Verify that your application’s
<provider>declaration inAndroidManifest.xmlincludesandroid:exported="true"while testing on debug builds. - If testing on a rooted device or Android Virtual Device (AVD) emulator, switch to root mode using
adb rootbefore executing the content query. Root access bypasses standard provider permission checks.
Mastering ADB content commands empowers Android developers and QA engineers to inspect database states, inject test fixtures, and audit Content Provider security without writing custom boilerplate code.