Я правильно понимаю что ContentProvider это некая сущность которая позволяет обращяться к Sql через URI или через специальный интерфейс ContentProvider. Также она позволяет решать могут ли другие приложения обращяться к базе данных внутри данного приложение если стоит значение exported true? И еще вопрос когда мы используем SqliteDatabaseHelper мы получается используем ContentProvider программно? ни как не могу найти нормальную статью или объяснение это сущности ContentProvider! Везде говорится как его использовать, но нигде нет инфы конкретно что это такое.
Отслеживать
user181100
задан 13 апр 2017 в 15:55
3,451 13 13 серебряных знаков 45 45 бронзовых знаков
Документация от Google на русском: developer.android.com/guide/topics/providers/…
13 апр 2017 в 19:59
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
ContentProvider — это как следует из его названия провайдер некоего контента. Это необязательно SQL данные — это может быть все что угодно.
Например, можно легко представить, что приложение содержит в себе некие данные, ну скажем, приложение игра морской бой и в нем хранятся данные о последних шагах игрока. Теперь стоит задача — высунуть данные о ходах наружу, причем высунуть безопасно. Вот тут то и приходит на помощь ContentProvider . Правила обращения с ContentProvider довольно просты, декларируется Uri типа:
Startandroid: Урок 101. Создаем свой ContentProvider (разработка Android приложений)
content://[authority]/[path]
рекомендуется использовать в качестве authority имя пакета с префиксом поясняющим суть провайдера, например для нашего морского боя можно было бы применить:
com.my.application.package.seabattledataprovider
смысл path — указании собственно самого запроса, здесь пример запроса на получение второго шага в нашей игре:
content://com.my.application.package.seabattledataprovider/data?step=2
Синтаксис задания Uri задан документом RFC 2396 и является универсальным, класс Uri поддерживает разбор этого синтаксиса.
Для реализации ContentProvider надо написать свой класс наследующий от класса ContentProvider , где основным методом является метод query() , в котором полученный Uri надо распарсить по заданным разработчиком самим правилам и вернуть данные в виде Cursor , который не всегда является SQLiteCursor . Если данные не являются SQL данными, то надо писать собственный класс, который наследует от класса AbstractCursor
Теперь, чтобы получить данные из нашей игры в морской бой, надо из любого места (если провайдер экспортирован, то и из любого другого приложения) вызвать:
context.getContentResolver(«content://com.my.application.package.seabattledataprovider/data?step=2», null, null, null, null);
В ответ мы получим курсор с нашими данными.
И еще вопрос когда мы используем SqliteDatabaseHelper мы получается используем ContentProvider программно?
Источник: ru.stackoverflow.com
Основные компоненты Android: Activity, Service, Content provider и Broadcast receiver на практике
Введение в ContentProvider
Для упрощения доступа к общим данным, таким как файлы мультимедиа, контакты и сведения о календаре, операционная система Android использует поставщики содержимого. В этой статье представлен класс ContentProvider, а также два примера его использования.
Общие сведения о поставщиках содержимого
Поставщик содержимого инкапсулирует репозиторий данных и предоставляет API для доступа к нему. Поставщик существует как часть приложения Android, которая обычно также предоставляет пользовательский интерфейс для отображения данных и управления ими.
Основное преимущество поставщика содержимого заключается в том, что другие приложения могут легко получать доступ к инкапсулированным данным с помощью клиентского объекта поставщика (называемого ContentResolver). Вместе поставщик и сопоставитель содержимого обеспечивают единообразный работающий между приложениями API для доступа к данным. Этот API прост в создании и использовании. Любое приложение может использовать ContentProviders для внутреннего управления данными, а также для их предоставления другим приложениям.
ContentProvider также необходимо для приложения, чтобы предоставить настраиваемые варианты поиска, или если вы хотите предоставить возможность копирования сложных данных из приложения для вставки в другие приложения. В этом документе показано, как получить доступ к ContentProviders и создавать его с помощью Xamarin.Android.
Эта статья имеет следующую структуру.
- Принцип работы — обзор того, ContentProvider для чего предназначен компонент и как он работает.
- Использование поставщика содержимого — пример доступа к списку контактов.
- Использование ContentProvider для совместного использования данных — создание и использование ContentProvider в одном приложении.
ContentProviders и курсоры, работающие с их данными, часто используются для заполнения ListViews. Дополнительные сведения об использовании этих классов см. в руководстве Xamarin.Android ListView.
ContentProviders , предоставляемые Android (или другими приложениями), — это простой способ включения в приложение данных из других источников. Эти классы позволяют получать доступ к данным, таким как список контактов, фотографии или события календаря в приложении, и предоставлять пользователю возможность взаимодействовать с ними.
Настраиваемые классы ContentProviders — это удобный способ упаковки данных для использования в собственном приложении или для использования другими приложениями (включая особые варианты использования, такие как пользовательский поиск и копирование или вставка).
В темах этого раздела приводятся некоторые простые примеры использования и написания кода ContentProvider .
Связанные ссылки
- Демонстрационный пример для ContactsAdapter
- SimpleContentProvider (пример)
- Поставщики содержимого
- Класс ContentProvider
- Класс ContentResolver
- Класс ListView
- Класс CursorAdapter
- Класс UriMatcher
- Пространство имен Android.Provider
- Класс ContactsContract
Источник: learn.microsoft.com
Контент-провайдер (Content Provider) в основном используется для реализации функции обмена данными между различными приложениями и предоставляет полный набор механизмов, позволяющих одной программе получать доступ к данным в другой программе, а также обеспечивает доступ к данным. безопасность. В настоящее время использование поставщиков контента является стандартным способом обмена данными между программами в Android.
В отличие от двух глобально читаемых и записываемых режимов работы в хранилище файлов и хранилище SharedPreferences, поставщики контента могут выбирать, какая часть данных является общей для обеспечения конфиденциальности данных в нашей программе. Нет риска утечки.
2. Использование контент-провайдеров
Мы обычно используем контент-провайдеров для запроса данных:
Cursor cursor = getContentResolver().query(final Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
- Ури, укажите таблицу под определенную программу
- проекция, указав имена столбцов запроса
- выберите условия запроса, эквивалентные условиям после где в операторе sql
- selectionArgs, предоставляя определенные значения для заполнителей в выборе
- orderBy указывает порядок сортировки результатов запроса
- cancellationSignal, отменить семафор текущей операции
Если вы написали код SQLite, вы должны быть хорошо знакомы с этим методом! Когда вы закончите читать принцип, лежащий в основе механизма ContentProvider, вы поймете это!
Если вы хотите получить доступ к данным, совместно используемым в поставщике контента, вы должны использовать класс CotentResolver. Вы можете получить экземпляр этого класса с помощью метода getContentResolver () в Context. ContentResolver предоставляет ряд методов для выполнения операций CRUD (добавление, удаление, модификация и поиск) над данными.
Метод insert () используется для добавления данных, метод update () используется для обновления данных, а метод delete () используется для удаления данных. Метод query () используется для запроса данных. Это похоже на операцию базы данных SQLite?
В отличие от SQLiteDatabase, методы добавления, удаления, изменения и поиска в ContentResolver не принимают параметр имени таблицы, но вместо этого используют параметр Uri. Этот параметр называется URI содержимого. URI содержимого устанавливает уникальный идентификатор для данных в поставщике содержимого, состоящий в основном из двух частей: права доступа и пути.
Полномочия используются для различения различных приложений. Как правило, во избежание конфликтов имена пакетов используются для именования. Например, имя пакета программы — com.example.app, тогда полномочия, соответствующие программе, могут быть названы com.example.app.provider. Путь используется для различения разных таблиц в одном приложении и обычно добавляется после прав доступа.
Например, в базе данных программы есть две таблицы: table1 и table 2. В настоящее время вы можете назвать путь как / table1 и / table2, а затем объединить полномочия и путь, и URI контента станет com.example. app.provider / table1 и com.example.app.provider / table2. Тем не менее, все еще трудно идентифицировать эти две строки как два URI контента. Нам также нужно добавить объявление протокола в начало строки. Поэтому наиболее стандартный формат содержимого URI выглядит следующим образом:
content://com.example.app.provider/table1 content://com.example.app.provider/table2
После получения строки URI содержимого нам также необходимо проанализировать ее в объект Uri, прежде чем она будет передана в качестве параметра. Метод синтаксического анализа также довольно прост: код выглядит следующим образом:
Uri uri = new Uri.parse(«content://com.example.app.provider/table1»);
Просто вызовите статический метод Uri parse (), чтобы разобрать строку URI содержимого в объект URI.
Теперь мы можем запросить данные в таблице 1 через этот объект Uri. Код выглядит так:
Cursor cursor = getContentResolver() .query( uri,projection,selection,selectionArgs,sortOrder );
Параметры, полученные методом query (), аналогичны параметрам, полученным методом query () в SQLiteDatabase, но в целом это немного проще: в конце концов, это доступ к данным в других программах. Нет необходимости создавать сложные операторы запроса. Индексы подробно объясняют параметры, полученные запросом в поставщике контента:
После того, как запрос завершен, объект Cursor по-прежнему возвращается.В настоящее время мы можем читать данные по одному из объекта Cursor. Идея чтения по-прежнему состоит в том, чтобы обойти этот объект Cursor и затем извлечь данные один за другим, код выглядит следующим образом:
if (cursor! = null) >
Запрос будет выполнен, поэтому оставшиеся добавления, удаления и модификации, естественно, не нужны. Код выглядит следующим образом:
// Добавить данные ContentValues values = new ContentValues(); values.put(«Column1″,»text»); values.put(«Column2″,»1″); getContextResolver.insert(uri,values); // Удалить данные getContextResolver.delete(uri,»column2 = ?»,new String[]< «1» >); // Обновить данные ContentValues values = new ContentValues(); values.put («Столбец1», «Изменить данные»); getContextResolver.update(uri,values,»column1 = ? and column2 = ?»,new String[]);
3. Как создать контент-провайдер из собственного приложения?
Как упоминалось ранее, если вы хотите реализовать функцию совместного использования данных между программами, официально рекомендованным способом является использование поставщика контента. Вы можете создать новый класс для наследования класса ContentProvider для создания своего собственного поставщика контента. Класс ContentProvider имеет 6 абстрактных методов. Когда мы наследуем его от подкласса, нам нужно переписать все 6 методов. Новый MyProvider наследует класс ContentProvider. Код выглядит следующим образом:
Я полагаю, что из этих 6 методов, помимо методов, которые вы можете использовать для добавления, удаления, изменения и проверки, вы можете не знать оставшиеся два метода. Ниже описываются эти методы один за другим:
1.onCreate () метод:
Вызывается при инициализации поставщика контента. Операции создания и обновления базы данных обычно выполняются здесь. Возвращает true, если поставщик содержимого был успешно инициализирован, или false, если произошел сбой. Обратите внимание, что поставщик контента будет инициализирован только тогда, когда ContentResolver пытается получить доступ к данным в нашей программе.
2. запрос () метод:
data Запрос данных у поставщика контента. Используйте параметр uri, чтобы определить, к какой таблице следует запрашивать, параметр проекции, чтобы определить, какой столбец запроса, параметры selection и selectionArgs для ограничения, какие строки запрашивать, параметр sortOrder для сортировки результатов и результаты запроса сохраняются в объекте Cursor и возвращаются. ,
3.insert () метод:
Добавьте часть данных поставщику контента. Для определения добавляемой таблицы используйте параметр uri. Данные для добавления сохраняются в параметре values. После завершения добавления верните URI, представляющий эту новую запись.
4.update () метод:
Обновите существующие данные в поставщике контента. Используйте параметр uri, чтобы определить, какие данные таблицы обновляются. Новые данные сохраняются в параметре values. Параметры selection и selectionArgs используются для ограничения того, какие строки обновляются. Число затронутых строк будет возвращено в качестве возвращаемого значения.
5.delete () метод:
Удалить данные из контент-провайдера. Используйте параметр uri, чтобы определить, какие данные таблицы удаляются. Параметры selection и selectionArgs используются для ограничения того, какие строки удаляются. Количество удаленных строк возвращается в качестве возвращаемого значения.
6. getType () метод:
Возвращает соответствующий тип MIME на основе переданного URI содержимого.
Вы можете видеть, что почти каждый метод будет принимать параметр Uri, который также является параметром, который передается при вызове методов добавления, удаления и изменения ContentResolver. Теперь нам нужно проанализировать входящие параметры Uri и проанализировать таблицы и данные, к которым ожидает доступ вызывающая сторона.
Напомним, что стандартный URI контента записывается так:
content://com.example.app.provider/table1
Это означает, что вызывающая сторона ожидает доступа к данным в таблице table1 приложения com.example.app. Кроме того, мы можем добавить идентификатор после URI содержимого, как показано ниже:
content://com.example.app.provider/table1/1
Это означает, что вызывающая сторона ожидает доступа к данным с идентификатором 1 в таблице table1 приложения com.example.app.
Формат URI содержимого в основном включает два вышеуказанных типа: конец пути указывает, что вы хотите получить доступ ко всем данным в таблице, а результат id указывает, что вы хотите получить доступ к данным с соответствующим идентификатором в таблице. Мы можем использовать подстановочные знаки для сопоставления URI контента в этих двух форматах. Правила следующие:
- *: Соответствует любому символу любой длины.
- #: Соответствует любому числу любой длины.
Таким образом, формат URI контента, который соответствует любой таблице, может быть записан как:
content://com.example.app.provider/*
Формат URI контента, который соответствует любой строке данных в таблице, может быть записан как:
content://com.example.app.provider/table1/#
Далее, мы можем легко реализовать функцию сопоставления URI контента с помощью класса UriMatcher. UriMatcher предоставляет метод addURI (). Этот метод принимает три параметра и может передавать права доступа, путь и пользовательский код. Этот пользовательский код фактически является окончательным значением int.
Таким образом, когда вызывается метод match () UriMatcher, можно передать объект Uri, а возвращаемое значение — это пользовательский код, который может соответствовать объекту Uri. Используя этот код, мы можем определить ожидания вызывающего К какой таблице обращаются? Измените приведенный выше код MyProvider следующим образом:
Приведенный выше код является просто демонстрацией с использованием метода query () в качестве примера. На самом деле реализация метода insert (), update (), delete () похожа на метод query (), все они содержат параметр Uri, а затем один и тот же Используйте метод match () UriMatcher, чтобы определить, к какой таблице хочет обратиться вызывающий объект, а затем выполните соответствующие операции с данными в таблице.
Кроме того, есть еще один метод, с которым вы не знакомы. Это метод getType (). Это метод, который все поставщики контента должны предоставить, чтобы получить тип MIME, соответствующий объекту Uri. Строка MIME, соответствующая URI контента, в основном состоит из 3 частей. Android определил следующий формат для этих 3 частей:
- Должен начинаться с vnd
- Если URI содержимого заканчивается путем, за ним следует android.cursor.dir /, а если URI содержимого заканчивается идентификатором, за ним следует android.cursor.item /.
- Затем перейдите к vnd. .
Таким образом, для содержимого URI содержимого: //com.example.app.provider/table1 его соответствующий тип MIME можно записать в виде:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
Для содержимого URI содержимого: //com.example.app.provider/table1/1 соответствующий ему тип MIME можно записать в виде:
vnd.android.cursor.item/vnd.com.example.app.provider.table1
Теперь мы можем продолжить улучшать содержимое в классе MyProvider. На этот раз для реализации логики метода getType () код выглядит следующим образом:
Здесь создается полный поставщик контента, и теперь можно использовать любое приложение.
ContentResolver для доступа к данным в нашей программе. Итак, как мы можем гарантировать, что личные данные не будут вытекать? На самом деле, эта проблема была решена неосознанно благодаря хорошему механизму поставщика контента. Поскольку все операции CRUD должны выполняться путем сопоставления соответствующего формата URI контента, и, конечно, мы не можем добавить URI личных данных в UriMatcher, поэтому внешние части этой программы вообще не могут быть доступны внешним программам, и проблемы безопасности не Он существует.
Хорошо, вы уже знаете шаги по созданию провайдера контента. Давайте посмотрим на него и познакомимся с другими людьми.
Функция обмена данными последовательности.
Это еще не конец? Все мы знаем, что четыре основных компонента должны быть зарегистрированы в файле AndroidManifest.xml. Теперь, когда законченный поставщик контента записан, следующим шагом является регистрация в файле AndroidManifest.xml, после чего можно использовать поставщик контента. Давайте рассмотрим пример. Код упаковки стандартного поставщика контента выглядит следующим образом:
Зарегистрируйте поставщика содержимого в файле AndroidManifest.xml с тегами .
Это завершает процесс создания полного поставщика контента.
4. Принципиальный механизм работы ContentPrivoder
На самом деле, к поставщикам контента можно обращаться по всем программам, что можно рассматривать как способ межпроцессного взаимодействия. Фактически, ядром его принципа является Binder.
Источник: russianblogs.com
