android contentProvider

2016-08-22  本文已影响105人  MrMagicWang

除了共享内存(SDCard)的数据外,其他包括SQLite、SharedPreferences都是仅限于被当前所创建的应用访问,而无法使它们的数据在应用程序之间交换数据,所以Android提供了ContentProvider,ContentProvider具有以下特点:

ContentProvider可以理解为一个Android应用对外开放的接口, 只要是符合它所定义的Uri格式的请求,均可以正常访问执行操作。
访问ContentProvider

ContentProvider 实例通过处理来自其他应用的请求来管理对结构化数据集的访问。所有形式的访问最终都会调用 ContentResolver,后者接着调用ContentProvider的具体方法来获取访问权限

一般使用Context.getContentResolver()方法获取ContentResolver对象。

ContentResolver 可提供insert、query、update、delete等方法.

例如,要从用户字典提供程序中获取字词及其区域设置的列表,则需调用 ContentResolver.query()。

// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
    UserDictionary.Words.CONTENT_URI,   
    mProjection,                        
    mSelectionClause                  
    mSelectionArgs,                     
    mSortOrder);                        
query() 参数 SELECT 关键字/参数 备注
Uri FROM table_name Uri 映射至名为 table_name 的提供程序中的表。
projection col,col,col,... projection 是应该为检索到的每个行包含的列的数组。
selection WHERE col = value selection 会指定选择行的条件。
selectionArgs (没有完全等效项。选择参数会替换选择子句中 ? 的占位符。)
sortOrder ORDER BY col,col,... sortOrder 指定行在返回的 Cursor 中的显示顺序。
内容 URI

在Android中,Uri是一种比较常见的资源访问方式。每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

<srandard_prefix>://<authority>/<data_path>/<id>

content://user_dictionary/words
content://com.example.app.provider/table3/1
//对应由 表table3中1标识的行的内容 URI。
content://com.example.app.provider/table3/1/name
//对应由 表table3中1标识的行的name字段内容 URI。
UriMatcher

UriMatcher会将内容 URI“模式”映射到整型值。 可以在一个 switch 语句中使用这些整型值,为匹配特定模式的一个或多个内容 URI 执行相应操作。

内容 URI 模式使用通配符匹配内容 URI:

*:匹配由任意长度的任何有效字符组成的字符串
#:匹配由任意长度的数字字符组成的字符串

假设一个具有权限 com.example.app.provider的提供程序能识别以下指向表的内容 URI:

content://com.example.app.provider/table1:一个名为 table1 的表
content://com.example.app.provider/table2/dataset1:一个名为 dataset1 的表
content://com.example.app.provider/table2/dataset2:一个名为 dataset2 的表
content://com.example.app.provider/table3:一个名为 table3 的表

可以使用以下内容 URI 模式:

content://com.example.app.provider/*
//匹配提供程序中的任何内容 URI。
content://com.example.app.provider/table2/*:
//匹配表 dataset1 和表 dataset2 的内容 URI,但不匹配 table1 或 table3 的内容 URI。
content://com.example.app.provider/table3/#
//匹配 table3 中单个行的内容 URI,
//如 content://com.example.app.provider/table3/6 对应由 6 标识的行的内容 URI。

方法 addURI() 会将权限和路径映射到一个整型值。 方法 match() 会返回 URI 的整型值。switch 语句会在查询整个表与查询单个记录之间进行选择:

public class ExampleProvider extends ContentProvider {
      ...
    // Creates a UriMatcher object.
    private static final UriMatcher sUriMatcher;

    sUriMatcher.addURI("com.example.app.provider", "table3", 1);

    sUriMatcher.addURI("com.example.app.provider", "table3/#", 2);
    ...
    // Implements ContentProvider.query()
    public Cursor query(Uri uri, String[] projection, String selection, 
                String[] selectionArgs, String sortOrder) {
        ...
        switch (sUriMatcher.match(uri)) {
            // If the incoming URI was for all of table3
            case 1:
                if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
                break;
            // If the incoming URI was for a single row
            case 2:
                /*
                 Because this URI was for a single row, the _ID value part is
                 present. Get the last path segment from the URI;
                 this is the _ID value.Then, append the value to the WHERE 
                 clause for the query
                 */
                selection = selection + "_ID = " uri.getLastPathSegment();
                break;

            default:
            ...
                // If the URI is not recognized, you should do some error handling here.
        }
        // call the code to actually do the query
    }
创建ContentProvider

在Android中,如果要创建自己的内容提供者的时候,需要扩展抽象类ContentProvider,并重写其中定义的各种方法。然后在AndroidManifest.xml文件中注册该ContentProvider。

创建ContentProvider的步骤:

  1. 创建一个ContentProvider的子类。
  1. 定义内容Uri
  1. 创建SQLiteOpenHelper的子类,创建一个用于存储内容的数据库。
  1. 在ContentProvider的子类中实现query()、insert()、update()、delete()、getType()、onCreate()方法。
  1. 在AndroidManifest.xml文件中注册自定义的ContentProvider。
    <provider.../>:一般只需要设置两个属性即可访问,一些额外的属性就是为了设置访问权限而存在的:
    android:name:provider的响应类。
    android:authorities:Provider的唯一标识,用于Uri匹配,一般为ContentProvider类的全名。

在实现ContentProvider的方法时需要注意一下几点:

上一篇 下一篇

猜你喜欢

热点阅读