Контент-провайдеры (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) { } }
Данный класс по принципу синглтона организует доступ к базе данных и, кроме того, создает саму базу данных и добавляет в нее начальные данные.