Контент-провайдеры в Android с примером
В 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 содержимого вставленной строки. Этот метод используется для обновления полей существующей строки. Он возвращает количество обновленных строк. Этот метод используется для удаления существующих строк. Возвращает количество удаленных строк. Этот метод возвращает многоцелевое расширение почты Интернета (MIME). тип данных для данного URI контента. При создании поставщика контента система Android вызывает этот метод немедленно инициализирует поставщика. запрос() вставлять() Обновить() удалять() getType () onCreate ()
Пример
Основная цель поставщика контента - служить центральным хранилищем данных, где пользователи могут хранить и извлекать данные. Доступ к этому репозиторию предоставляется и другим приложениям, но безопасным образом для удовлетворения различных требований пользователя. Ниже приведены шаги, необходимые для внедрения поставщика контента. В этом поставщике контента пользователь может хранить имена людей и может извлекать сохраненные данные. Более того, другое приложение также может получить доступ к сохраненным данным и может отображать данные.
Note: Following steps are performed on Android Studio version 4.0
Создание поставщика контента:
Шаг 1. Создайте новый проект
- Щелкните Файл, затем Новый => Новый проект.
- Выберите язык как Java / Kotlin.
- Выберите пустое действие в качестве шаблона
- Выберите минимальный 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. Создание класса поставщика содержимого
- Щелкните File, затем New => Other => ContentProvider.
- Назовите ContentProvider
- Определите полномочия (это может быть что угодно, например com.demo.user.provider )
- Выберите параметр « Экспортировано и включено».
- Выберите язык как 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 // 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 // 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 private
|