Контент-провайдеры в Android с примером

Опубликовано: 5 Января, 2022

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

URI контента

Content URI (Uniform Resource Identifier) - ключевая концепция поставщиков контента. Для доступа к данным от поставщика контента URI используется в качестве строки запроса.

Structure of a Content URI: content://authority/optionalPath/optionalID

Подробная информация о различных частях Content URI:

  • content: // - Обязательная часть URI, поскольку она представляет, что данный URI является Content URI.
  • авторитет - обозначает имя поставщика содержимого, например, контакты, браузер и т. д. Эта часть должна быть уникальной для каждого поставщика содержимого.
  • optionalPath - указывает тип данных, предоставляемых поставщиком содержимого. Это важно, поскольку эта часть помогает поставщикам контента поддерживать различные типы данных, которые не связаны друг с другом, например аудио- и видеофайлы.
  • optionalID - это числовое значение, которое используется, когда есть необходимость получить доступ к определенной записи.

Если идентификатор упоминается в URI, то это URI на основе идентификатора, в противном случае - URI на основе каталога.

Операции в Content Provider

В Content Provider возможны четыре основных операции, а именно: создание , чтение , обновление и удаление . Эти операции часто называют операциями CRUD .

  • Создать: операция по созданию данных в контент-провайдере.
  • Чтение: используется для получения данных от поставщика содержимого.
  • Обновление: для изменения существующих данных.
  • Удалить: удалить существующие данные из хранилища.

Работа контент-провайдера

Компоненты пользовательского интерфейса приложений Android, такие как Activity и Fragments, используют объект CursorLoader для отправки запросов на ContentResolver. Объект ContentResolver отправляет запросы (например, создание, чтение, обновление и удаление) ContentProvider в качестве клиента. После получения запроса ContentProvider обрабатывает его и возвращает желаемый результат. Ниже приведена диаграмма, на которой эти процессы представлены в наглядной форме.

Создание поставщика контента

Ниже приведены шаги, которые необходимо выполнить для создания поставщика контента:

  • Создайте класс в том же каталоге, где находится этот файл MainActivity, и этот класс должен расширять базовый класс ContentProvider.
  • Чтобы получить доступ к контенту, определите адрес URI провайдера контента.
  • Создайте базу данных для хранения данных приложения.
  • Реализуйте шесть абстрактных методов класса ContentProvider.
  • Зарегистрируйте поставщика содержимого в файле AndroidManifest.xml с помощью тега <provider> .

Ниже приведены шесть абстрактных методов и их описание, которые необходимо переопределить как часть класса ContenProvider:

Абстрактный метод

Описание



запрос()

Метод, который принимает аргументы и извлекает данные из

желаемый стол. Данные удаляются как объект курсора.

вставлять()

Вставить новую строку в базу данных контент-провайдера.

Он возвращает URI содержимого вставленной строки.

Обновить()

Этот метод используется для обновления полей существующей строки.

Он возвращает количество обновленных строк.

удалять()

Этот метод используется для удаления существующих строк.

Возвращает количество удаленных строк.

getType ()

Этот метод возвращает многоцелевое расширение почты Интернета (MIME).

тип данных для данного URI контента.

onCreate ()

При создании поставщика контента система Android вызывает

этот метод немедленно инициализирует поставщика.

Пример

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

Note: Following steps are performed on Android Studio version 4.0

Создание поставщика контента:

Шаг 1. Создайте новый проект

  1. Щелкните Файл, затем Новый => Новый проект.
  2. Выберите язык как Java / Kotlin.
  3. Выберите пустое действие в качестве шаблона
  4. Выберите минимальный SDK в соответствии с вашими потребностями.

Шаг 2. Измените файл strings.xml

Здесь хранятся все строки, используемые в действии.

XML

< resources >
< string name = "app_name" >Content_Provider_In_Android</ string >
< string name = "hintText" >Enter User Name</ string >
< string name = "heading" >Content Provider In Android</ string >
< string name = "insertButtontext" >Insert Data</ string >
< string name = "loadButtonText" >Load Data</ string >
</ resources >

Шаг 3. Создание класса поставщика содержимого

  1. Щелкните File, затем New => Other => ContentProvider.
  2. Назовите ContentProvider
  3. Определите полномочия (это может быть что угодно, например com.demo.user.provider )
  4. Выберите параметр « Экспортировано и включено».
  5. Выберите язык как Java / Kotlin

Этот класс расширяет базовый класс ContentProvider и переопределяет шесть абстрактных методов. Ниже приведен полный код для определения поставщика содержимого.

Джава

package com.example.contentprovidersinandroid;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;
public class MyContentProvider extends ContentProvider {
public MyContentProvider() {
}
// defining authority so that other application can access it
static final String PROVIDER_NAME = "com.demo.user.provider" ;
// defining content URI
static final String URL = " content:// " + PROVIDER_NAME + "/users" ;
// parsing the content URI
static final Uri CONTENT_URI = Uri.parse(URL);
static final String id = "id" ;
static final String name = "name" ;
static final int uriCode = 1 ;
static final UriMatcher uriMatcher;
private static HashMap<String, String> values;
static {
// to match the content URI
// every time user access table under content provider
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// to access whole table
uriMatcher.addURI(PROVIDER_NAME, "users" , uriCode);
// to access a particular row
// of the table
uriMatcher.addURI(PROVIDER_NAME, "users/*" , uriCode);
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case uriCode:
return "vnd.android.cursor.dir/users" ;
default :
throw new IllegalArgumentException( "Unsupported URI: " + uri);
}
}
// creating the database
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null ) {
return true ;
}
return false ;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
qb.setProjectionMap(values);
break ;
default :
throw new IllegalArgumentException( "Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == "" ) {
sortOrder = id;
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null ,
null , sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// adding data to the database
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(TABLE_NAME, "" , values);
if (rowID > 0 ) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null );
return _uri;
}
throw new SQLiteException( "Failed to add a record into " + uri);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0 ;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.update(TABLE_NAME, values, selection, selectionArgs);
break ;
default :
throw new IllegalArgumentException( "Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null );
count; return
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0 ;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.delete(TABLE_NAME, selection, selectionArgs);
break ;
default :
throw new IllegalArgumentException( "Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null );
count; return
}
// creating object of database
// to perform query
private SQLiteDatabase db;
// declaring name of the database
static final String DATABASE_NAME = "UserDB" ;
// declaring table name of the database
static final String TABLE_NAME = "Users" ;
// declaring version of the database
static final int DATABASE_VERSION = 1 ;
// sql query to create the table
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);" ;
// creating a database
private static class DatabaseHelper extends SQLiteOpenHelper {
// defining a constructor
DatabaseHelper(Context context) {
super (context, DATABASE_NAME, null , DATABASE_VERSION);
}
// creating a table in the database
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// sql query to drop a table
// having similar name
"DROP TABLE IF EXISTS " db.execSQL( + TABLE_NAME);
onCreate(db);
}
}
}

Котлин

package com.example.contentprovidersinandroid
import android.content.*
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteException
import android.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
class MyContentProvider : ContentProvider() {
companion object {
// defining authority so that other application can access it
const val PROVIDER_NAME = "com.demo.user.provider"
// defining content URI
const val URL = " content:// $PROVIDER_NAME/users"
// parsing the content URI
val CONTENT_URI = Uri.parse(URL)
const val id = "id"
const val name = "name"
const val uriCode = 1
var uriMatcher: UriMatcher? = null
private val values: HashMap<String, String>? = null
// declaring name of the database
const val DATABASE_NAME = "UserDB"
// declaring table name of the database
const val TABLE_NAME = "Users"
// declaring version of the database
const val DATABASE_VERSION = 1
// sql query to create the table
const val CREATE_DB_TABLE =
( " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);" )
init {
// to match the content URI
// every time user access table under content provider
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
// to access whole table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users" ,
uriCode
)
// to access a particular row
// of the table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users/*" ,
uriCode
)
}
}
override fun getType(uri: Uri): String? {
return when (uriMatcher!!.match(uri)) {
uriCode -> "vnd.android.cursor.dir/users"
else -> throw IllegalArgumentException( "Unsupported URI: $uri" )
}
}
// creating the database
override fun onCreate(): Boolean {
val context = context
val dbHelper =
DatabaseHelper(context)
db = dbHelper.writableDatabase
return if (db != null ) {
true
} else false
}
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
): Cursor? {
var sortOrder = sortOrder
val qb = SQLiteQueryBuilder()
qb.tables = TABLE_NAME
when (uriMatcher!!.match(uri)) {
uriCode -> qb.projectionMap = values
else -> throw IllegalArgumentException( "Unknown URI $uri" )
}
if (sortOrder == null || sortOrder === "" ) {
sortOrder = id
}
val c = qb.query(
db, projection, selection, selectionArgs, null ,
null , sortOrder
)
c.setNotificationUri(context!!.contentResolver, uri)
return c
}
// adding data to the database
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val rowID = db!!.insert(TABLE_NAME, "" , values)
if (rowID > 0 ) {
val _uri =
ContentUris.withAppendedId(CONTENT_URI, rowID)
context!!.contentResolver.notifyChange(_uri, null )
return _uri
}
throw SQLiteException( "Failed to add a record into $uri" )
}
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.update(TABLE_NAME, values, selection, selectionArgs)
else -> throw IllegalArgumentException( "Unknown URI $uri" )
}
context!!.contentResolver.notifyChange(uri, null )
count return
}
override fun delete(
uri: Uri,
selection: String?,
selectionArgs: Array<String>?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.delete(TABLE_NAME, selection, selectionArgs)
else -> throw IllegalArgumentException( "Unknown URI $uri" )
}
context!!.contentResolver.notifyChange(uri, null )
count return
}
// creating object of database
// to perform query
private var db: SQLiteDatabase? = null
// creating a database