---
title: Content Providers - Beeper Developer Docs
description: Query chats, messages, and contacts from Beeper using Android Content Provider APIs
---

Build Android apps and connected devices that integrate with Beeper using standard Android [content provider](https://developer.android.com/guide/topics/providers/content-providers) APIs. Content providers encapsulate data and provide mechanisms for defining data security, serving as the standard interface between processes.

Experimental

Content providers are experimental and APIs are subject to change.

### What you can build

- **Universal Search** - Search across all chats and messages
- **Widgets & Dashboards** - Display chat summaries and unread counts
- **Automation** - Send messages and react to changes
- **Wearables** - Integrate with watches and IoT devices

### Key features

- **Authority**: `com.beeper.api`
- **Permissions**: Runtime (request at first use)
- **Data Access**: Chats, messages, contacts
- **Operations**: Query, insert, observe changes
- **Protocol Support**: WhatsApp, Telegram, Signal, and more

## Quick start

1. **Add permissions to your manifest**

   AndroidManifest.xml

   ```
   <uses-permission android:name="com.beeper.android.permission.READ_PERMISSION" />
   <uses-permission android:name="com.beeper.android.permission.SEND_PERMISSION" />
   ```

   These are custom Beeper permissions. Declare them in the manifest and request them at runtime with a permission prompt.

   ```
   // Request at runtime (e.g., in an Activity or Fragment)
   val requestPermissions = registerForActivityResult(
       ActivityResultContracts.RequestMultiplePermissions()
   ) { results ->
       val hasRead = results["com.beeper.android.permission.READ_PERMISSION"] == true
       val hasSend = results["com.beeper.android.permission.SEND_PERMISSION"] == true
       // Handle granted/denied states
   }


   requestPermissions.launch(arrayOf(
       "com.beeper.android.permission.READ_PERMISSION",
       "com.beeper.android.permission.SEND_PERMISSION"
   ))
   ```

2. **Query recent chats**

   ```
   import androidx.core.net.toUri


   val uri = "content://com.beeper.api/chats?limit=50".toUri()
   contentResolver.query(uri, null, null, null, null)?.use { cursor ->
       val titleIdx = cursor.getColumnIndexOrThrow("title")
       val previewIdx = cursor.getColumnIndexOrThrow("messagePreview")
       val unreadIdx = cursor.getColumnIndexOrThrow("unreadCount")


       while (cursor.moveToNext()) {
           val title = cursor.getString(titleIdx)
           val preview = cursor.getString(previewIdx)
           val unread = cursor.getInt(unreadIdx)
           // Display chat info in your UI
       }
   }
   ```

3. **Send a message**

   ```
   import android.net.Uri
   import androidx.core.net.toUri


   val message = "Hello from my app!"
   val roomId = "!room:server.com"


   val result = contentResolver.insert(
       ("content://com.beeper.api/messages?" +
        "roomId=$roomId&text=${Uri.encode(message)}").toUri(),
       null
   )


   result?.let {
       val messageId = it.getQueryParameter("messageId")
       // Message sent successfully
   }
   ```

4. **Observe changes**

   ```
   import android.os.Handler
   import android.os.Looper
   import android.database.ContentObserver
   import androidx.core.net.toUri


   contentResolver.registerContentObserver(
       "content://com.beeper.api/chats".toUri(),
       true,
       object : ContentObserver(Handler(Looper.getMainLooper())) {
           override fun onChange(selfChange: Boolean) {
               // Re-query and refresh your UI
           }
       }
   )
   ```

   Only `content://com.beeper.api/chats` currently emits change notifications. Observers for `messages` or `contacts` will not fire.

## Common use cases

- [Unread Counter](#tab-panel-21)
- [Search Messages](#tab-panel-22)
- [Protocol Filter](#tab-panel-23)

```
// Get total unread count across all chats
val uri = "content://com.beeper.api/chats/count?isUnread=1".toUri()
val cursor = contentResolver.query(uri, null, null, null, null)
val unreadTotal = cursor?.use {
    if (it.moveToFirst()) {
        it.getInt(it.getColumnIndexOrThrow("count"))
    } else 0
} ?: 0
```

```
// Search with surrounding context
val searchTerm = "meeting"
val uri = ("content://com.beeper.api/messages?" +
          "query=${Uri.encode(searchTerm)}" +
          "&contextBefore=2&contextAfter=2").toUri()


contentResolver.query(uri, null, null, null, null)?.use { cursor ->
    val textIdx = cursor.getColumnIndexOrThrow("text_content")
    val matchIdx = cursor.getColumnIndexOrThrow("is_search_match")


    while (cursor.moveToNext()) {
        val text = cursor.getString(textIdx)
        val isMatch = cursor.getInt(matchIdx) == 1
        // Highlight matches in UI
    }
}
```

```
// Get WhatsApp chats only
val uri = "content://com.beeper.api/chats?protocol=whatsapp".toUri()
contentResolver.query(uri, null, null, null, null)?.use { cursor ->
    // Process WhatsApp-specific chats
}
```

## Performance tips

Best practices

1. **Always Set Limits** - Default limit is 100, but always specify `limit` to avoid large queries
2. **Use Filters** - Filter by `roomIds`, `protocol`, or other parameters to reduce data
3. **Batch Operations** - Combine multiple filters in one query instead of multiple queries
4. **Lifecycle Awareness** - Register/unregister observers with your component lifecycle

## Supported protocols

| Protocol        | Identifier         | Features |
| --------------- | ------------------ | -------- |
| WhatsApp        | `whatsapp`         | Full     |
| Telegram        | `telegram`         | Full     |
| Signal          | `signal`           | Full     |
| Matrix/Beeper   | `beeper`, `matrix` | Full     |
| Discord         | `discord`          | Full     |
| Slack           | `slack`            | Full     |
| Google Messages | `gmessages`        | Full     |
| Others          | Various            | Query    |

## Learn more

- **[API Reference →](/android/content-providers/api-reference/index.md)** - Complete API documentation for all endpoints
- **[Integration Guide →](/android/content-providers/integration-guide/index.md)** - Permissions, notifications, and troubleshooting
- **[Android Docs →](https://developer.android.com/guide/topics/providers/content-provider-basics)** - Official content provider documentation
