Android 实施基本的内容提供者类

示例

1)创建合同类

合同类定义用于帮助应用程序处理内容提供者的内容URI,列名,意图动作和其他功能的常量。提供商不自动包含合同类别;提供者的开发人员必须定义它们,然后将其提供给其他开发人员。

提供者通常只有一个权限,即作为其Android内部名称的权限。为避免与其他提供程序发生冲突,请使用唯一的内容授权。由于此建议也适用于Android软件包名称,因此您可以将提供者权限定义为包含提供者的软件包名称的扩展名。例如,如果您的Android软件包名称为com.example.appname,则应授予您的提供商权限com.example.appname.provider。

public class MyContract {
    public static final String CONTENT_AUTHORITY = "com.example.myApp";
    public static final String PATH_DATATABLE = "dataTable";
    public static final String TABLE_NAME = "dataTable";
}

内容URI是标识提供者中数据的URI。内容URI包括整个提供程序的符号名称(其权限)和指向表或文件的名称(路径)。可选的id部分指向表中的单个行。ContentProvider的每种数据访问方法都有一个内容URI作为参数。这使您可以确定要访问的表,行或文件。在合同类中定义它们。

public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DATATABLE).build();

// 定义表的所有列和所需的常用功能

2)创建助手类

助手类管理数据库的创建和版本管理。

public class DatabaseHelper extends SQLiteOpenHelper {

    // 数据库结构发生变化时增加版本
    public static final int DATABASE_VERSION = 1;
    // 文件系统中数据库的名称,您可以选择任何形式
    public static final String DATABASE_NAME = "weather.db";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //首次创建数据库时调用。这是
        // 创建表和表的初始填充。
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //在需要升级数据库时调用。实施
        // 应该使用此方法删除表,添加表或执行其他任何操作
        // 需要升级到新的架构版本。
    }
}

3)创建一个扩展ContentProvider类的类

public class MyProvider extends ContentProvider {

public DatabaseHelper dbHelper;

public static final UriMatcher matcher = buildUriMatcher();
public static final int DATA_TABLE = 100;
public static final int DATA_TABLE_DATE = 101;

UriMatcher将权限和路径映射到整数值。该方法match()返回URI的唯一整数值(可以是任意数字,只要它是唯一的)。switch语句在查询整个表和查询单个记录之间进行选择。如果URI是Table的Content URI,我们的UriMatcher返回100;如果URI指向该表中的特定行,则返回101。您可以使用#通配符来匹配任何数字并*匹配任何字符串。

public static UriMatcher buildUriMatcher() {
    UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE,        DATA_TABLE);
    uriMatcher.addURI(CONTENT_AUTHORITY,MyContract.PATH_DATATABLE+ "/#", DATA_TABLE_DATE);
    return uriMatcher;
}

重要提示:addURI()呼叫顺序很重要!UriMatcher的显示顺序为:从第一个添加到最后一个。由于通配符喜欢#和*很贪婪,因此您需要确保正确订购了URI。例如:

uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*",       2);

是正确的排序,因为匹配者/example在诉诸/*匹配之前会先查找。如果这些方法调用被反向调用并且您调用了uriMatcher.match("/example"),则UriMatcher一旦遇到/*路径,将停止寻找匹配项并返回错误结果!

然后,您将需要覆盖以下功能:

onCreate():初始化您的提供商。Android系统在创建您的提供程序后立即调用此方法。请注意,只有在ContentResolver对象尝试访问它之前,才创建您的提供程序。

@Override
public boolean onCreate() {
    dbhelper = new DatabaseHelper(getContext());
    return true;
}

getType():返回与内容URI对应的MIME类型

@Override
public String getType(Uri uri) {
    final int match = matcher.match(uri);
    switch (match) {
        case DATA_TABLE:
            returnContentResolver.CURSOR_DIR_BASE_TYPE+ "/" +MyContract.CONTENT_AUTHORITY+ "/" + MyContract.PATH_DATATABLE;
        case DATA_TABLE_DATE:
            returnContentResolver.ANY_CURSOR_ITEM_TYPE+ "/" +MyContract.CONTENT_AUTHORITY+ "/" + MyContract.PATH_DATATABLE;
        default:
            throw new UnsupportedOperationException("未知的Uri: " + uri);

    }
}

query():从提供商处检索数据。使用参数选择要查询的表,要返回的行和列以及结果的排序顺序。将数据作为Cursor对象返回。

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    Cursor retCursor = dbHelper.getReadableDatabase().query(
        MyContract.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
    retCursor.setNotificationUri(getContext().getContentResolver(), uri);
    return retCursor;
}

在您的提供程序中插入新行。使用参数选择目标表并获取要使用的列值。返回新插入行的内容URI。

@Override
public Uri insert(Uri uri, ContentValues values)
{
    final SQLiteDatabase db = dbHelper.getWritableDatabase();
    long id = db.insert(MyContract.TABLE_NAME, null, values);
    return ContentUris.withAppendedId(MyContract.CONTENT_URI, ID);
}

delete():从提供商中删除行。使用参数选择表和要删除的行。返回删除的行数。

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    int rowsDeleted = db.delete(MyContract.TABLE_NAME, selection, selectionArgs);
    getContext().getContentResolver().notifyChange(uri, null);
    return rowsDeleted;
}

update():更新提供商中的现有行。使用参数选择要更新的表和行并获取新的列值。返回更新的行数。

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    int rowsUpdated = db.update(MyContract.TABLE_NAME, values, selection, selectionArgs);
    getContext().getContentResolver().notifyChange(uri, null);
    return rowsUpdated;
}

4)更新清单文件

<provider
        android:authorities="com.example.myApp"
        android:name=".DatabaseProvider"/>