Главная страница

моб разраб. Лабораторные работы с 1 по 21. Лабораторная работа Использование значений строк и цветов


Скачать 5.49 Mb.
НазваниеЛабораторная работа Использование значений строк и цветов
Анкормоб разраб
Дата05.03.2022
Размер5.49 Mb.
Формат файлаdocx
Имя файлаЛабораторные работы с 1 по 21.docx
ТипЛабораторная работа
#383909
страница19 из 20
1   ...   12   13   14   15   16   17   18   19   20

Контент-провайдеры


Контент-провайдеры предоставляют интерфейс для публикации и потребления структурированных наборов данных, основанный на URI с использованием простой схемы content://. Их использование позволяет отделить код приложения от данных, делая программу менее чувствительной к изменениям в источниках данных.

Для взаимодействия с контент-провайдером используется уникальный URI, который обычно формируется следующим образом:

content://<домен-разработчика-наоборот>.provider.<имя-приложения>/<путь-к-даным>

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

Контент-провайдеры являются единственным способом доступа к данным других приложений и используются для получения результатов запросов, обновления, добавления и удаления данных. Если у приложения есть нужные полномочия, оно может запрашивать и модифицировать соответствующие данные, принадлежащие другому приложению, в том числе данные стандартных БД Android. В общем случае, контент-провайдеры следует создавать только тогда, когда требуется предоставить другим приложениям доступ к данным вашего приложения. В остальных случаях рекомендуется использовать СУБД (SQLite). Тем не менее, иногда контент-провайдеры используются внутри одного приложения для поиска и обработки специфических запросов к данным.

Использование контент-провайдеров

Для доступа к данным какого-либо контент-провайдера используется объект класса ContentResolver, который можно получить с помощью метода getContentResolver контекста приложения для связи с поставщиком в качестве клиента:

ContentResolver cr = getApplicationContext().getContentResolver();

Объект ContentResolver взаимодействует с объектом контент-провайдера, отправляя ему запросы клиента. Контент-провайдер обрабатывает запросы и возвращает результаты обработки.

Контент-провайдеры представляют свои данные потребителям в виде одной или нескольких таблиц подобно таблицам реляционных БД. Каждая строка при этом является отдельным «объектом» со свойствами, указанными в соответствующих именованных полях. Как правило, каждая строка имеет уникальный целочисленный индекс и именем

«_id», который служит для однозначной идентификации требуемого объекта.

Контент-провайдеры, обычно предоставляют минимум два URI для работы с данными: один для запросов, требующих все данные сразу, а другой – для обращения к конкретной

«строке». В последнем случае в конце URI добавляется /<номер-строки> (который совпадает с индексом «_id»).
Запросы на получение данных

Запросы на получение данных похожи на запросы к БД, при этом используется метод query объекта ContentResolver. Ответ также приходит в виде курсора, «нацеленного» на результирующий набор данных (выбранные строки таблицы):

ContentResolver cr = getContentResolver();
// получить данные всех контактов

Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
// получить все строки, где третье поле имеет конкретное

// значение и отсортировать по пятому полю String where = KEY_COL3 + "=" + requiredValue; String order = KEY_COL5;
Cursor someRows = cr

.query(MyProvider.CONTENT_URI, null, where, null, order);
Извлечение данных-результатов запроса с помощью курсора было рассмотрено ранее.
Изменение данных

Для изменения данных применяются методы insert, update и delete объекта ContentResolver. Для массовой вставки также существует метод bulkInsert.

Пример добавления данных:

ContentResolver cr = getContentResolver(); ContentValues newRow = new ContentValues();

// повторяем для каждого поля в строке: newRow.put(COLUMN_NAME, newValue);

Uri myRowUri = cr.insert(SampleProvider.CONTENT_URI, newRow);
// Массовая вставка:

ContentValues[] valueArray = new ContentValues[5];
// здесь заполняем массив
// делаем вставку

int count = cr.bulkInsert(MyProvider.CONTENT_URI, valueArray);
При вставке одного элемента метод insert возвращает URI вставленного элемента, а при массовой вставке возвращается количество вставленных элементов.
Пример удаления:

ContentResolver cr = getContentResolver();

// удаление конкретной строки cr.delete(myRowUri, null, null);
// удаление нескольких строк String where = "_id < 5";

cr.delete(MyProvider.CONTENT_URI, where, null);
Пример изменения:

ContentValues newValues = new ContentValues();
newValues.put(COLUMN_NAME, newValue); String where = "_id < 5";
getContentResolver().update(MyProvider.CONTENT_URI, newValues, where, null);

Лабораторная работа «получение списка контактов»

Для чтения информации о контактах используется контент-провайдер ContactsContract, точнее, один из его подклассов. Для этой лабораторной работы воспользуемся провайдером ContactsContract.Contacts. Для чтения контактов приложению требуются полномочия READ_CONTACTS.

  1. Добавьте несколько контактов в эмуляторе (поскольку требуется только отображаемое имя контакта, остальные поля можно не заполнять :).

  2. Создайте новый проект ContactsSample.

  3. Выведите имена всех контактов (с помощью ListView), используя для получения информации URI ContactsContract.Contacts.CONTENT_URI. Необходимое имя поля для привязки адаптера найдите среди статических констант класса ContactsContract.Contacts.


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

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

ContentProvider и переопределить метод onCreate, чтобы проинициализировать источник

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

public class NewProvider extends ContentProvider {

public final static Uri CONTENT_URI=Uri.parse("URI провайдера"); @Override

public int delete(Uri uri, String selection, String[] selectionArgs) {

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

return 0;

}
@Override

public String getType(Uri uri) {

// Возвращает тип MIME для указанных объектов(объекта)

return null;

}
@Override

public Uri insert(Uri uri, ContentValues values) {

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

return null;

}
@Override

public boolean onCreate() {

// Инициализация источника данных

return false;

}
@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

// Стандартный запрос

return null;

}
@Override

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

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

return 0;

}

}
Как говорилось выше, URI обычно выглядят примерно так:

content://<домен-разработчика-наоборот>.provider.<имя-приложения>/<путь-к-даным>

Традиционно URI должны быть представлены двумя способами, одним – для доступа ко всем значениям определенного типа, другой – для указания на конкретный экземпляр данных.

Например, URI content://com.android.provider.metropicker/stations мог бы использоваться для получения списка всех станций (метро), а content://com.android.provider.metropicker/stations/17 – для станции с индексом 17.

При создании контент-провайдера обычно применяется статический объект класса UriMatcher, который служит для определения деталей запроса к контент-провайдеру. Использование UriMatcher позволяет «разгрузить» логику программы и избежать множественного сравнения строковых объектов за счет централизованного «отображения» URI разных видов на целочисленные константы. Особенно он полезен в случаях, когда создаваемый контент-провайдер обслуживает разные URI для доступа к одному и тому же источнику данных. Использовать UriMatcher очень просто: внутри класса контент- провайдера можно добавить такой код:
// Константы для разных типов запросов private static final int ALL_STATIONS= 1; private static final int SINGLE_STATION= 2;
private static final UriMatcher uriMatcher;
// Заполнение UriMatcher'а

// Если URI оканчивается на /stations - это запрос про все станции

// Если на stations/[ID] - про конкретную станцию

static {

uriMatcher= new UriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI("com.example.provider.metropicker", "stations",

ALL_STATIONS);

uriMatcher.addURI("com.example.provider.metropicker", "stations/#",

SINGLE_STATION);

}

В дальнейшем полученный в запросе к контент-провайдеру URI проверяется в методах класса следующим образом:

@Override

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

switch (uriMatcher.match(uri)) {

case ALL_STATIONS:

// Вернуть курсор, указывающий на выборку со

// всеми станциями
case SINGLE_STATION:

// Вытащить ID станции из URI:

String _id = uri.getPathSegments().get(1);
// Вернуть курсор, указывающий на выборку с одной

// станцией.
}

return null;

}
При наполнении объекта UriMatcher шаблонами могут применять в «#» и «*» в качестве специальных символов: # в шаблоне совпадает с любым числом, а * - с любым текстом.

Кроме уникальных URI, используемым создаваемым контент-провайдером, для определения клиентами типа возвращаемых по запросу данных используются уникальные типы MIME. Метод getType класса ContentProvider обычно возвращает один тип данных для массовой выборки, а другой – для одиночных записей. В нашем случае это могло бы

выглядеть так:

@Override

public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case ALL_STATIONS:

return "vnd.com.example.cursor.dir/station";

case SINGLE_STATION:

return "vnd.com.example.cursor.item/station";

default:

throw new IllegalArgumentException("Unsupported URI: " + uri);

}

}
Для того, что бы Android знал о существовании и мог использовать (через ContentResolver) ваш контент-провайдер, его нужно описать в Манифесте приложения. Минимальное описание выглядит так:


android:name=".NewProvider" android:authorities="com.android.provider.metropicker">

В данном случае указаны только обязательные атрибуты элемента
:
имя класса контент-провайдера и его область ответственности. Более полную информацию о возможных атрибутах можно получить на сайте developer.android.com: http://developer.android.com/guide/topics/manifest/provider-element.html
Лабораторная работа «создание контент-провайдера»

Цель данной лабораторной работы – получить навыки создания собственных контент- провайдеров. В качестве основы возьмите упражнение «работа с SQLite с классом- адаптером» и замените прямое обращение к СУБД на взаимодействие с контент- провайдером, который будет инкапсулировать все взаимодействие с «настоящими» данными в отдельном классе.

1   ...   12   13   14   15   16   17   18   19   20


написать администратору сайта