Что такое android authorities в контент провайдере
Перейти к содержимому

Что такое android authorities в контент провайдере

  • автор:

Из чего состоит Content URI?

URI – Uniform Resource Identifier.
URI контента в андроиде – это объект класса Uri, который имеет структуру content://// .

content: – это схема. Константа content определена в документации как SCHEME_CONTENT. Именно схема говорит, что данный URI – это URI контента, а не, например, файла.

authority – идентифицирует ContentProvider . Обрабатывая запросы, ContentResolver использует authority , чтобы найти ContentProvider в системной таблице зарегистрированных провайдеров. После этого запросы делегируются в провайдер.

path используется контент провайдером, чтобы определить путь к данным. Обычно path соответствует названиям таблиц, используемых провайдером.

id – опциональная часть content URI и поддерживается не всеми провайдерами. Определяет строку в таблице провайдера. Метод insert() возвращает URI, содержащий id созданной строки.

Примеры content URI таблиц провайдера календарей:
Таблица календарей: content://com.android.calendar/calendars
Таблица событий: content://com.android.calendar/events

Content provider (Контент-провайдер)

Контент-провайдер или «Поставщик содержимого» (Content Provider) — это оболочка (wrapper), в которую заключены данные. Если ваше приложение использует базу данных SQLite, то только ваше приложение имеет к ней доступ. Но бывают ситуации, когда данные желательно сделать общими. Простой пример — ваши контакты из телефонной книги тоже содержатся в базе данных, но вы хотите иметь доступ к данным, чтобы ваше приложение тоже могло выводить список контактов. Так как вы не имеете доступа к базе данных чужого приложения, был придуман специальный механизм, позволяющий делиться своими данными всем желающим.

Поставщик содержимого применяется лишь в тех случаях, когда вы хотите использовать данные совместно с другими приложениями, работающих в устройстве. Но даже если вы не планируете сейчас делиться данными, то всё-равно можно подумать об реализации этого способа на всякий случай.

Content provider

В Android существует возможность выражения источников данных (или поставщиков данных) при помощи передачи состояния представления — REST, в виде абстракций, называемых поставщиками содержимого. Базу данных SQLite можно заключить в поставщик содержимого. Чтобы получить данные из поставщика содержимого или сохранить в нём новую информацию, нужно использовать набор REST-подобных идентификаторов URI. Например, если бы вам было нужно получить набор книг из поставщика содержимого, в котором заключена электронная библиотека, вам понадобился бы такой URI (по сути запрос к получению всех записей таблицы books):

content://com.android.book.bookprovider/books

Чтобы получить из библиотеки конкретную книгу (например, книгу №23), будет использоваться следующий URI (отдельный ряд таблицы):

content://com.android.book.bookProvider/books/23

Любая программа, работающая в устройстве, может использовать такие URI для доступа к данным и осуществления с ними определенных операций. Следовательно, поставщики содержимого играют важную роль при совместном использовании данных несколькими приложениями.

Встроенные поставщики

В Android используются встроенные поставщики содержимого (пакет android.provider). Вот неполный список поставщиков содержимого:

  • Browser
  • CallLog
  • Contacts
    • People
    • Phones
    • Photos
    • Groups
    • Audio
      • Albums
      • Artists
      • Genres
      • Playlists
      • Thumbnails

      На верхних уровнях иерархии располагаются базы данных, на нижних — таблицы. Так, Browser, СаllLog, Contacts, MediaStore и Settings — это отдельные базы данных SQLite, инкапсулированные в форме поставщиков. Обычно такие базы данных SQLite имеют расширение DB и доступ к ним открыт только из специальных пакетов реализации (implerentation package). Любой доступ к базе данных из-за пределов этого пакета осуществляется через интерфейс поставщика содержимого.

      Создание собственного контент-провайдера

      Для создания собственного контент-провайдера нужно унаследоваться от абстрактного класса ContentProvider:

       public class MyContentProvider extends ContentProvider

      В классе необходимо реализовать абстрактные методы query(), insert(), update(), delete(), getType(), onCreate(). Прослеживается некоторое сходство с созданием обычной базы данных.

      А также его следует зарегистрировать в манифесте с помощью тега provider с атрибутами name и authorities. Тег authorities служит для описания базового пути URI, по которому ContentResolver может найти базу данных для взаимодействия. Данный тег должен быть уникальным, поэтому рекомендуется использовать имя вашего пакета, чтобы не произошло путаницы с другими приложениями, например:

      Источник поставщика содержимого аналогичен доменному имени сайта. Если источник уже зарегистрирован, эти поставщики содержимого будут представлены гиперссылками, начинающимися с соответствующего префикса источника:

       content://ru.alexanderklimov.provider.notepad/ 

      Итак, поставщики содержимого, как и веб-сайты, имеют базовое доменное имя, действующее как стартовая URL-страница.

      Необходимо отметить, что поставщики содержимого, используемые в Android, могут иметь неполное имя источника. Полное имя источника рекомендуется использовать только со сторонними поставщиками содержимого. Поэтому вам иногда могут встретиться поставщики содержимого, состоящие из одного слова, например contacts, в то время как полное имя такого поставщика содержимого — com.google.android.contacts.

      В поставщиках содержимого также встречаются REST-подобные гиперссылки, предназначенные для поиска данных и работы с ними. В случае описанной выше регистрации унифицированный идентификатор ресурса, предназначенный для обозначения каталога или коллекции записей в базе данных NotePadProvider, будет иметь имя:

       content://ru.alexanderklimov.provider.notepad/notes 

      URI для идентификации отдельно взятой записи будет иметь вид:

       content://ru.alexanderklimov.provider.notepad/notes/# 

      Символ # соответствует конкретной записи (ряд таблицы). Ниже приведено еще несколько примеров URI, которые могут присутствовать в поставщиках содержимого:

       content://media/internal/images content://media/external/images content://contacts/people/ content://contacts/people/23 

      Обратите внимание — здесь поставщики содержимого content://media и content://contacts имеют неполную структуру. Это обусловлено тем, что данные поставщики содержимого не являются сторонними и контролируются Android.

      Структура унифицированных идентификаторов содержимого (Content URI)

      Для получения данных из поставщика содержимого нужно просто активировать URI. Однако при работе с поставщиком содержимого найденные таким образом данные представлены как набор строк и столбцов и образуют объект Android cursor. Рассмотрим структуру URI, которую можно использовать для получения данных.

      Унифицированные идентификаторы содержимого (Content URI) в Android напоминают HTTP URI, но начинаются с content и строятся по следующему образцу:

       content://*/*/* 
       content://authority-name/path-segment1/path-segment2/etc. 

      Вот пример URI, при помощи которого в базе данных идентифицируется запись, имеющая номер 23:

       content://ru.alexanderklimov.provider.notepad/notes/23 

      После content: в URI содержится унифицированный идентификатор источника, который используется для нахождения поставщика содержимого в соответствующем реестре. Часть URI ru.alexanderklimov.provider.notepad представляет собой источник.

      /notes/23 — это раздел пути (path section), специфичный для каждого отдельного поставщика содержимого. Фрагменты notes и 23 раздела пути называются сегментами пути (path segments). Одной из функций поставщика содержимого является документирование и интерпретация раздела и сегментов пути, содержащихся в URI.

      UriMatcher

      Провайдер имеет специальный объект класса UriMatcher, который получает данные снаружи и на основе полученной информации создаёт нужный запрос к базе данных.

      Вам нужно задать специальные константы, по которым провайдер будет понимать дальнейшие действия. Если используется одна таблица, то обычно применяют две константы — любые два целых числа, например, 100 для таблицы и 101 для отдельного ряда таблицы. Схематично можно изобразить так.

      URI pattern Code Contant name
      content://ru.alexanderklimov.provider.notepad/notes 100 NOTES
      content://ru.alexanderklimov.provider.notepad/notes/# 101 NOTES_ID

      В коде с помощью switch создаётся ветвление — хотим ли мы получить информацию о всей таблице (код 100) или к конкретному ряду (код 101).

      Приложение может быть сложным и иметь несколько таблиц. Тогда и констант будет больше. Например, так.

      URI pattern Code Contant name
      content://com.android.contacts/contacts 1000 CONTACTS
      content://com.android.contacts/contacts/# 1001 CONTACTS_ID
      content://com.android.contacts/lookup/* 1002 CONTACTS_LOOKUP
      content://com.android.contacts/lookup/*/# 1003 CONTACTS_LOOKUP_ID
      . . .
      content://com.android.contacts/data 3000 DATA
      content://com.android.contacts/data/# 3001 DATA_ID
      . . .

      Символ решётки (#) отвечает за число, а символ звёздочки (*) за строку.

      Метод query()

      Метод query() является обязательным для класса ContentProvider. Если мы используем контент-провайдер для обращения к базе данных, то в нём вызывает одноимённый метод SQLiteDatabase. Состав метода практически идентичен.

       @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) < . cursor = database.query(GuestEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); . > 
       URI: content://com.example.android.cathouse/cats/3 Projection: Selection: "_id=?" Selection Args:
       SELECT id, name FROM cats WHERE _id=3 

      Вам нужно программно получить необходимые данные для аргументов метода. Обратите внимание на метод ContentUris.parseId(uri), который возвращает последний сегмент адреса, в нашем случае число 3, для Selection Args.

      Метод insert()

      Метод insert() содержит два параметра — URI и ContenValues. Первый параметр работает аналогично, как в методе query(). Вторая вставляет данные в нужные колонки таблицы.

      Для вставки используется вспомогательный метод insertGuest().

      Структурирование МIМЕ-типов в Android

      Как веб-сайт возвращает тип MIME для заданной гиперссылки (это позволяет браузеру активировать программу, предназначенную для просмотра того или иного типа контента), так и в поставщике содержимого предусмотрена возможность возвращения типа MIME для заданного URI. Благодаря этому достигается определенная гибкость при просмотре данных. Если мы знаем, данные какого именно типа получим, то можем выбрать одну или несколько программ, предназначенных для представления таких данных. Например, если на жестком диске компьютера есть текстовый файл, мы можем выбрать несколько редакторов, которые способны его отобразить.

      Типы MIME работают в Android почти так же, как и в НТТР. Вы запрашиваете у контент-провайдера тип MIME определенного поддерживаемого им URI, и поставщик содержимого возвращает двухчастную последовательность символов, идентифицирующую тип MIME в соответствии с принятыми стандартами.

      Обозначение MIME состоит из двух частей: типа и подтипа. Ниже приведены примеры некоторых известных пар типов и подтипов MIME:

      text/html
      text/css
      text/xml
      image/jpeg
      audio/mp3
      video/mp4
      application/pdf
      application/msword

      Основные зарегистрированные типы содержимого:

      application
      audio
      image
      message
      model
      multipart
      text
      video

      В Android применяется схожий принцип для определения типов MIME. Обозначение vnd в типах MIME в Android означает, что данные типы и подтипы являются нестандартными, зависящими от производителя. Для обеспечения уникальности в Android типы и подтипы разграничиваются при помощи нескольких компонентов, как и доменные имена. Кроме того, типы MIME в Android, соответствующие каждому типу содержимого, существуют в двух формах: для одиночной записи и для нескольких записей.

      1. Тип и подтип должны быть уникальными для того типа содержимого, который они представляют. Обычно это каталог с элементами или отдельный элемент. В контексте Android разница между каталогом и элементом может быть не такой очевидной, как кажется на первый взгляд.
      2. Если тип или подтип не являются стандартными, им должен предшествовать префикс vnd (обычно это касается конкретных видов записи).
      3. Обычно типы и подтипы относятся к определенному пространству имен в соответствии с вашими нуждами.

      Необходимо еще раз подчеркнуть этот момент: основной тип MIME для коллекции элементов, возвращаемый командой cursor в Android, всегда должен иметь вид vnd.android.cursor.dir, а основной тип MIME для одиночного элемента, находимый командой cursor в Android, — вид vnd.android.cursor.item. Если речь идет о подтипе, то поле для маневра расширяется, как в случае с vnd.googlе.note; после компонента vnd. вы можете свободно выбирать любой устраивающий вас подтип.

      ContentResolver

      Каждый объект Content, принадлежащий приложению, включает в себя экземпляр класса ContentResolver, который можно получить через метод getContentResolver().

       ContentResolver contentResolver = getContentResolver(); 

      ContentResolver используется для выполнения запросов и транзакций от активности к контент-провайдеру. ContentResolver включает в себя методы для запросов и транзакций, аналогичные тем, что содержит ContentProvider. Объекту ContentResolver не нужно знать о реализации контент-провайдера, с которым он взаимодействует — любой запрос всего лишь принимают путь URI, в котором указано, к какому объекту ContentProvider необходимо обращаться.

      Что такое android authorities в контент провайдере

      Продолжим рабоу с проектом из прошлой темы и добавим в него класс AppProvider , который собственно и будет представлять провайдер контента:

      package com.example.friendsproviderapp; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class AppProvider extends ContentProvider < private AppDatabase mOpenHelper; private static final UriMatcher sUriMatcher = buildUriMatcher(); public static final int FRIENDS = 100; public static final int FRIENDS_ID = 101; private static UriMatcher buildUriMatcher()< final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); // content://com.example.friendsprovider/FRIENDS matcher.addURI(FriendsContract.CONTENT_AUTHORITY, FriendsContract.TABLE_NAME, FRIENDS); // content://com.example.friendsprovider/FRIENDS/8 matcher.addURI(FriendsContract.CONTENT_AUTHORITY, FriendsContract.TABLE_NAME + "/#", FRIENDS_ID); return matcher; >@Override public boolean onCreate() < mOpenHelper = AppDatabase.getInstance(getContext()); return true; >@Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) < final int match = sUriMatcher.match(uri); SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); switch(match)< case FRIENDS: queryBuilder.setTables(FriendsContract.TABLE_NAME); break; case FRIENDS_ID: queryBuilder.setTables(FriendsContract.TABLE_NAME); long taskId = FriendsContract.getFriendId(uri); queryBuilder.appendWhere(FriendsContract.Columns._ID + " = " + taskId); break; default: throw new IllegalArgumentException("Unknown URI: "+ uri); >SQLiteDatabase db = mOpenHelper.getReadableDatabase(); return queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); > @Nullable @Override public String getType(@NonNull Uri uri) < final int match = sUriMatcher.match(uri); switch(match)< case FRIENDS: return FriendsContract.CONTENT_TYPE; case FRIENDS_ID: return FriendsContract.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI: "+ uri); >> @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db; Uri returnUri; long recordId; if (match == FRIENDS) < db = mOpenHelper.getWritableDatabase(); recordId = db.insert(FriendsContract.TABLE_NAME, null, values); if (recordId >0) < returnUri = FriendsContract.buildFriendUri(recordId); >else < throw new SQLException("Failed to insert: " + uri.toString()); >> else < throw new IllegalArgumentException("Unknown URI: " + uri); >return returnUri; > @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String selectionCriteria = selection; if(match != FRIENDS && match != FRIENDS_ID) throw new IllegalArgumentException("Unknown URI: "+ uri); if(match==FRIENDS_ID) < long taskId = FriendsContract.getFriendId(uri); selectionCriteria = FriendsContract.Columns._ID + " = " + taskId; if ((selection != null) && (selection.length() >0)) < selectionCriteria += " AND (" + selection + ")"; >> return db.delete(FriendsContract.TABLE_NAME, selectionCriteria, selectionArgs); > @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String selectionCriteria = selection; if(match != FRIENDS && match != FRIENDS_ID) throw new IllegalArgumentException("Unknown URI: "+ uri); if(match==FRIENDS_ID) < long taskId = FriendsContract.getFriendId(uri); selectionCriteria = FriendsContract.Columns._ID + " = " + taskId; if ((selection != null) && (selection.length() >0)) < selectionCriteria += " AND (" + selection + ")"; >> return db.update(FriendsContract.TABLE_NAME, values, selectionCriteria, selectionArgs); > >

      В итоге получится следующий проект:

      Создание Content Provider в Android и Java

      Класс провайдера контента должен наследоваться от абстрактного класса ContentProvider , который определяет ряд методов для работы с данными, в частности, методы oncreate, query, insert, update, delete, getType.

      Для построения путей uri для запросов к источнику данных определен объект sUriMatcher, который представляет тип UriMatcher . Для его создания применяется метод buildUriMatcher :

      private static UriMatcher buildUriMatcher() < final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); // content://com.example.friendsprovider/FRIENDS matcher.addURI(FriendsContract.CONTENT_AUTHORITY, FriendsContract.TABLE_NAME, FRIENDS); // content://com.example.friendsprovider/FRIENDS/8 matcher.addURI(FriendsContract.CONTENT_AUTHORITY, FriendsContract.TABLE_NAME + "/#", FRIENDS_ID); return matcher; >

      С помощью метода addURI в объект UriMatcher добавляется определенный путь uri, используемый для отправки запроса. В качестве первого параметра addUri принимает название провайдера, который описывается константой CONTENT_AUTHORITY. Второй параметр — путь к данным в рамках источника данных — в данном случае это таблица friends. Третий параметр — числовой код, который позволяет разграничить характер операции. В данном случае у нас возможны два типа запросов — для обращения ко всей таблице, либо для обращения к отдельному объекту, вне зависимости идет ли речь о добавлении, получении, обновлении или удалении данных. Поэтому добавлюятся два uri. И для каждого используется один из двух числовых кодов — FRIENDS или FRIENDS_ID. Это могут быть абсолютно любые числовые коды. Но они позволят затем узнать, идет запрос ко всей таблице в целом или к какому-то одному определенному объекту.

      Метод oncreate() выполняет начальную инициализацию провайдера при его создании. В данном случае просто устанавливается используемая база данных:

      public boolean onCreate()

      Получение данных

      Для получения данных в провайдере определен метод query() .

      public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) < final int match = sUriMatcher.match(uri); SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); switch(match)< case FRIENDS: queryBuilder.setTables(FriendsContract.TABLE_NAME); break; case FRIENDS_ID: queryBuilder.setTables(FriendsContract.TABLE_NAME); long taskId = FriendsContract.getFriendId(uri); queryBuilder.appendWhere(FriendsContract.Columns._ID + " = " + taskId); break; default: throw new IllegalArgumentException("Unknown URI: "+ uri); >SQLiteDatabase db = mOpenHelper.getReadableDatabase(); return queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); >

      Данный метод должен принимать пять параметров:

      • uri : путь запроса
      • projection : набор столбцов, данные для которых надо получить
      • selection : выражение для выборки типа «WHERE Name = ? . «
      • selectionArgs : набор значений для параметров из selection (вставляются вместо знаков вопроса)
      • sortOrder : критерий сортировки, в качестве которого выступает имя столбца

      С помощью объекта SQLiteQueryBuilder создаем запрос sql, который будет выполняться. Для этого вначале получаем числовой код операции с помощью выражения sUriMatcher.match(uri) . То есть здесь мы узнаем, обращен запрос ко всей таблице (код FRIENDS) или к одному объекту (код FRIENDS_ID). Если запрос обращен ко всей таблице, то вызываем метод queryBuilder.setTables(FriendsContract.TABLE_NAME) .

      Если запрос идет к одному объекту, то в этом случае получаем собственно идентификатор объекта и с помощью метода appendWhere() добавляем условие для выборки по данному идентификатору.

      В конце собственно выполняем запрос с помощью метода queryBuilder.query() и возвращаем объект Cursor .

      Далее мы рассмотрим использование этого метода и возвращаемого им курсора.

      Добавление данных

      Для добавления данных применяется метод insert() :

      @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db; Uri returnUri; long recordId; if (match == FRIENDS) < db = mOpenHelper.getWritableDatabase(); recordId = db.insert(FriendsContract.TABLE_NAME, null, values); if (recordId >0) < returnUri = FriendsContract.buildFriendUri(recordId); >else < throw new SQLException("Failed to insert: " + uri.toString()); >> else < throw new IllegalArgumentException("Unknown URI: " + uri); >return returnUri; >

      Метод принимает два параметра:

      • uri : путь запроса
      • values : объект ContentValues, через который передаются добавляемые данные

      Для выполнения добавления выполняется метод db.insert , который возвращает идентификатор добавленного объекта:

      recordId = db.insert(TasksContract.TABLE_NAME, null, values);

      С помощью этого идентификатора создается и возвращается путь Uri к созданному объекту.

      Удаление данных

      public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String selectionCriteria = selection; if(match != FRIENDS && match != FRIENDS_ID) throw new IllegalArgumentException("Unknown URI: "+ uri); if(match==FRIENDS_ID) < long taskId = FriendsContract.getFriendId(uri); selectionCriteria = FriendsContract.Columns._ID + " = " + taskId; if ((selection != null) && (selection.length() >0)) < selectionCriteria += " AND (" + selection + ")"; >> return db.delete(FriendsContract.TABLE_NAME, selectionCriteria, selectionArgs); >

      Данный метод должен принимать три параметра:

      • uri : путь запроса
      • selection : выражение для выборки типа «WHERE Name = ? . «
      • selectionArgs : набор значений для параметров из selection (вставляются вместо знаков вопроса)

      При удалении мы можем реализовать один из двух сценариев: либо удалить из таблицы набор данных (например, друзей, у которых имя Том), либо удалить один объект по определенному идентифкатору. В случае если идет удаление по идентификатору, то к выражению выборки удаляемых данных в selection добавляется условие удаления по id:

      long taskId = FriendsContract.getFriendId(uri); selectionCriteria = FriendsContract.Columns._ID + " = " + taskId; if((selection != null) && (selection.length() > 0)) < selectionCriteria += " AND (" + selection + ")"; >count = db.delete(FriendsContract.TABLE_NAME, selectionCriteria, selectionArgs);

      Результатом удаления является количество удаленных строк в таблице.

      Обновление данных

      Для обновления данных применяется метод update() :

      public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) < final int match = sUriMatcher.match(uri); final SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String selectionCriteria = selection; if(match != FRIENDS && match != FRIENDS_ID) throw new IllegalArgumentException("Unknown URI: "+ uri); if(match==FRIENDS_ID) < long taskId = FriendsContract.getFriendId(uri); selectionCriteria = FriendsContract.Columns._ID + " = " + taskId; if ((selection != null) && (selection.length() >0)) < selectionCriteria += " AND (" + selection + ")"; >> return db.update(FriendsContract.TABLE_NAME, values, selectionCriteria, selectionArgs); >

      Данный метод должен принимать четыре параметра:

      • uri : путь запроса
      • values : объект ContentValues, который определяет новые значения
      • selection : выражение для выборки типа «WHERE Name = ? . «
      • selectionArgs : набор значений для параметров из selection (вставляются вместо знаков вопроса)

      Метод update во многом аналогичен методу delete за тем исключением, что в метод передаются данные типа ContentValues, которые передаются в метод db.update().

      AndroidManifest

      Но чтобы провайдер контента заработал, необходимо внести изменения в файл AndroidManifest.xml . К примеру, по умолчанию данный файл выглядит примерно следующим образом:

      И в конец элемента добавим определение провайдера:

      В элементе provider атрибут android:authorities указывает на название провайдера — в данном случае это название, которое определено в прошлой теме в константе CONTENT_AUTHORITY в классе FriendsContract, то есть com.example.friendsprovider . А атрибут android:name указывает на полное название класса провайдера с учетом его пакета. В моем случае пакет com.example.friendsproviderapp , а класс провайдера — AppProvider , поэтому в итоге получается com.example.friendsproviderapp.AppProvider .

      Вопросы с собеседований: Что такое контент-провайдер (Content Provider) в Android

      Контент-провайдер (Content Provider) в Android — это компонент, который предоставляет доступ к данным другим приложениям. Он представляет данные в виде таблицы или набора таблиц, похожих на таблицы в реляционной базе данных. Контент-провайдеры используются для совместного использования данных между приложениями, а также для предоставления доступа к данным, которые хранятся в приложении, другим приложениям.

      Контент-провайдеры предоставляют стандартизированный интерфейс для доступа к данным. Это означает, что приложения могут легко взаимодействовать с контент-провайдерами, даже если они написаны разными разработчиками.

      Они могут использоваться для хранения различных типов данных, включая контакты, календарь, фотографии и другие, в памяти устройства или в базе данных.

      Чтобы создать свой провайдер, необходимо реализовать класс, который расширяет класс ContentProvider . Этот класс должен реализовать несколько методов, которые предоставляют доступ к данным.

      • query() — используется для запроса данных из контент-провайдера.
      • insert() — используется для вставки данных в контент-провайдер.
      • update() — используется для обновления данных в контент-провайдер.
      • delete() — используется для удаления данных из контент-провайдера.

      Контент-провайдеры являются важным компонентом Android. Они позволяют приложениям совместно использовать данные и предоставляют доступ к данным, которые хранятся в приложении, другим приложениям.

      Вот несколько примеров использования контент-провайдеров:

      • Контакты: приложение для контактов может использовать контент-провайдер для хранения контактов. Другие приложения могут использовать этот контент-провайдер для доступа к контактам.
      • Календарь: приложение для календаря может использовать контент-провайдер для хранения событий календаря. Другие приложения могут использовать этот провайдер для доступа к событиям календаря.
      • Фотографии: приложение для фотографий может использовать контент-провайдер для хранения фотографий. Другие приложения могут использовать этот провайдер для доступа к фотографиям.

      Контент-провайдеры — это мощный инструмент, который может использоваться для совместного использования данных между приложениями.

      Вопросы с собеседований: что такое контент-провайдер (Content Provider) в Android

      Пример реализации контент-провайдера

      Вот пример реализации провайдера, который хранит список контактов:

      package com.example.contentprovidersuperexample; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; import android.util.Log; public class ContactProvider extends ContentProvider < private static final String TAG = "ContactProvider"; private static final String DATABASE_NAME = "contacts.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "contacts"; private static final String COLUMN_ID = "_id"; private static final String COLUMN_NAME = "name"; private static final String COLUMN_PHONE = "phone"; private DatabaseHelper mDatabaseHelper; @Override public boolean onCreate() < mDatabaseHelper = new DatabaseHelper(getContext()); return true; >@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) < SQLiteDatabase db = mDatabaseHelper.getReadableDatabase(); Cursor cursor = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; >@Override public String getType(Uri uri) < return ContentResolver.CURSOR_DIR_BASETYPE + "/" + TABLE_NAME; >@Override public Uri insert(Uri uri, ContentValues values) < SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); long null, values); getContext().getContentResolver().notifyChange(uri, null); return Uri.parse(uri + "/" + id); >@Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) < SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); int count = db.update(TABLE_NAME, values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return count; >@Override public int delete(Uri uri, String selection, String[] selectionArgs) < SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); int count = db.delete(TABLE_NAME, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); return count; >private static class DatabaseHelper extends SQLiteOpenHelper < public DatabaseHelper(Context context) < super(context, DATABASE_NAME, null, DATABASE_VERSION); >@Override public void onCreate(SQLiteDatabase db) < db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_NAME + " TEXT NOT NULL," + COLUMN_PHONE + " TEXT NOT NULL" + ");"); >@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) < db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); >>

      Этот класс предоставляет доступ к таблице контактов, которая имеет следующие столбцы:

      • _id — идентификатор контакта
      • name — имя контакта
      • phone — номер телефона контакта

      Он реализует основные методы, необходимые для доступа к данным:

      • query() — используется для запроса данных из контент-провайдера
      • insert() — используется для вставки данных в контент-провайдер
      • update() — используется для обновления данных в контент-провайдер
      • delete() — используется для удаления данных из контент-провайдера

      Если вы нашли опечатку — выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *