Контент-провайдеры (content providers) позволяют обращаться одним приложениям к данным других приложений. И мы таже можем сделать, чтобы другие приложения могули обращаться к данным нашего приложения через некоторый API. Для этого нам надо создать свой контент-провайдер. Рассмотрим как это сделать.
Вначале добавим в проект класс FriendsContract, который будет описывать основные значения, столбцы, адреса uri, используемые в контент-провайдере.
package com.example.friendsproviderapp;
import android.content.ContentUris;
import android.net.Uri;
public class FriendsContract {
static final String TABLE_NAME = "friends";
static final String CONTENT_AUTHORITY = "com.example.friendsprovider";
static final Uri CONTENT_AUTHORITY_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd." + CONTENT_AUTHORITY + "." + TABLE_NAME;
static final String CONTENT_ITEM_TYPE= "vnd.android.cursor.item/vnd." + CONTENT_AUTHORITY + "." + TABLE_NAME;
public static class Columns{
public static final String _ID = "_id";
public static final String NAME = "Name";
public static final String EMAIL = "Email";
public static final String PHONE = "Phone";
private Columns(){
}
}
static final Uri CONTENT_URI = Uri.withAppendedPath(CONTENT_AUTHORITY_URI, TABLE_NAME);
// создает uri с помощью id
static Uri buildFriendUri(long taskId){
return ContentUris.withAppendedId(CONTENT_URI, taskId);
}
// получает id из uri
static long getFriendId(Uri uri){
return ContentUris.parseId(uri);
}
}
С помощью константы TABLE_NAME определяется имя таблицы, к которой будет происходить обращение. А вложенный статический класс Columns описывает столбцы этой таблицы. То есть таблица будет называться "friends", а столбцы - "_id", "Name", "Email", "Phone". То есть условно говоря в таблице будут храниться данные о друзьях - имя, электронный адрес и номер телефона.
Константа CONTENT_AUTHORITY описывает название контент-провайдера. То есть в моем случае провайдер будет называться "com.example.friendsprovider". С помощью имени провайдера создается константа CONTENT_AUTHORITY_URI - универсальный локатор или своего рода путь, через который мы будем обращаться к провайдеру при выполнении с ним различных операций.
Также класс определяет две константы CONTENT_TYPE и CONTENT_ITEM_TYPE, которые определяют тип возвращаемого содержимого. Здесь есть два варианта:
возвращение набора данных и возвращение одного объекта. Значение, определяющее набор данных, строится по принципу "vnd.android.cursor.dir/vnd.[name].[table]", где в качестве [name]
обычно выступает глобально уникальный идентификатор, например, название провайдера или имя пакета провайдера. А в качестве [type], как правило,
используется имя таблицы. По похожей схеме строится второе значение, только вместо "dir" ставится "item".
Также в классе определяется вспомогательная константа CONTENT_URI, которая описывает путь для доступа к таблице friends. И также определяем два вспомогательных
метода: buildFriendUri() (возвращает uri для доступа к объекту по опреленному id) и getFriendId (для извлечения id из
переданного пути uri).
Далее добавим в проект новый класс AppDatabase:
package com.example.friendsproviderapp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class AppDatabase extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "friends.db";
public static final int DATABASE_VERSION = 1;
private static AppDatabase instance = null;
private AppDatabase(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
static AppDatabase getInstance(Context context){
if(instance == null){
instance = new AppDatabase(context);
}
return instance;
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE " + FriendsContract.TABLE_NAME + "(" +
FriendsContract.Columns._ID + " INTEGER PRIMARY KEY NOT NULL, " +
FriendsContract.Columns.NAME + " TEXT NOT NULL, " +
FriendsContract.Columns.EMAIL + " TEXT, " +
FriendsContract.Columns.PHONE + " TEXT NOT NULL)";
db.execSQL(sql);
// добавление начальных данных
db.execSQL("INSERT INTO "+ FriendsContract.TABLE_NAME +" (" + FriendsContract.Columns.NAME
+ ", " + FriendsContract.Columns.PHONE + ") VALUES ('Tom', '+12345678990');");
db.execSQL("INSERT INTO "+ FriendsContract.TABLE_NAME +" (" + FriendsContract.Columns.NAME
+ ", " + FriendsContract.Columns.EMAIL + ", " + FriendsContract.Columns.PHONE +
" ) VALUES ('Bob', 'bob@gmail.com', '+13456789102');");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Данный класс по принципу синглтона организует доступ к базе данных и, кроме того, создает саму базу данных и добавляет в нее начальные данные.