С помощью какого класса мы получаем доступ к Content Provider

Ответ

Для доступа к Content Provider используется класс ContentResolver. Он предоставляет CRUD-операции (query, insert, update, delete) через URI провайдера. Доступ к нему получают через context.getContentResolver().

Пример запроса данных:

val cursor = contentResolver.query(
    Uri.parse("content://com.example.provider/users"),
    null, null, null, null
)
cursor?.use {
    while (it.moveToNext()) {
        val name = it.getString(it.getColumnIndex("name"))
        Log.d("ContentProvider", "User: $name")
    }
}

Важно: запрашивать данные нужно в фоновом потоке, использовать Cursor.close() или use{}, и объявить нужные permissions в манифесте.

Ответ 18+ 🔞

Эй, слушай, вот объясню тебе про эту вашу Content Provider-хуйню, чтобы ты не ломал голову как последний ебанько. Представь, что у тебя есть сосед-жадина, который держит свои данные под замком, но иногда по доброте душевной позволяет тебе туда заглянуть. Вот Content Provider — это и есть такой сосед, только в мире андроида.

Чтобы с ним общаться, тебе нужен специальный посредник — ContentResolver. Это типа такого переводчика, который знает, как подойти к этому жадному соседу и попросить у него что-нибудь: посмотреть данные (query), добавить новые (insert), обновить старые (update) или нагло удалить (delete). Получаешь ты этого переводчика просто: context.getContentResolver(). Без него — нихуя не выйдет.

Допустим, тебе нужно вытащить список пользователей. Ты говоришь переводчику: «Сходи к тому провайдеру, который живёт по адресу content://com.example.provider/users, и спроси у него всё, что есть». Делается это вот так:

val cursor = contentResolver.query(
    Uri.parse("content://com.example.provider/users"),
    null, null, null, null
)
cursor?.use {
    while (it.moveToNext()) {
        val name = it.getString(it.getColumnIndex("name"))
        Log.d("ContentProvider", "User: $name")
    }
}

Смотри, что тут происходит. Ты получаешь Cursor — это такая хуйня, которая указывает на результат запроса, как стрелка на данные. И её, блядь, обязательно нужно закрывать, иначе будет утечка памяти, и твое приложение начнёт жрать оперативку как не в себя. Поэтому либо руками cursor.close() вызывай, либо, как умный человек, оборачивай в use{} — он сам всё закроет, когда дело сделано.

И ещё, ёпта, важный момент: не делай это в главном потоке! Представь, ты стоишь в очереди за колбасой, а кассирша вместо того, чтобы пробивать товар, начала глубоко и вдумчиво запрашивать данные из какой-то древней базы. Все за тобой будут стоять и материться, а интерфейс твоего приложения просто зависнет. Запросы к провайдеру — операция не мгновенная, поэтому выноси её в бэкграунд, в корутину или AsyncTask, если ты из прошлого века.

Ах да, и последнее: этот жадный сосед-провайдер может и не пустить тебя просто так. Часто ему нужно, чтобы ты в AndroidManifest.xml прописал соответствующие разрешения (permissions). Без этого — доверия ебать ноль, и на твой запрос он просто молча посмотрит, как на идиота. Так что не забудь объявить, что тебе можно, иначе вся твоя возня накроется медным тазом. Вот и вся магия, ничего сложного.