Создание провайдера контента. Часть 1. Определение контракта

Последнее обновление: 18.10.2021

Контент-провайдеры (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) {

    }
}

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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850