美文网首页
Android_06 ContentProvider

Android_06 ContentProvider

作者: MengkZhang | 来源:发表于2019-05-15 18:12 被阅读0次

官方API解释:
‘Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single [ContentResolver] interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don't need to share data amongst multiple applications you can use a database directly via [SQLiteDatabase].
详细信息参考API文档

ContentProvider官方文档

二:内容提供者使用步骤

  • 1,添加一个路径匹配器 详情见API文档
  • 2,在静态代码块中添加匹配规则
  • 3,暴露你想暴露的方法

示例代码:

1,创建工程 创建数据库表
2,创建一个类继承ContentProvider
3,在清单文件中注册内容提供者 添加一个要提示的属性

4,进行一系列的操作

/**
 * 内容提供者的使用步骤
 * @author Administrator
 *
 */
public class MyProvider extends ContentProvider {

    //[1]定义路径匹配器 详情见API文档
    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private static final int QUERYSECCEED = 0;
    private static final int INSERTSECCEED = 1;
    private static final int UPDATESECCEED = 2;
    private static final int DELETESECCEED = 3;
    private MyOpenHelper helper;

    //[2]在静态代码块中定义匹配规则 详情见API文档
    static
    {
        /*
         * addURI(String authority, String path, int code)
         * authority:在清单文件中注册时候设置的authority   com.mmk.provider
         * path:要匹配的路径  这里的一个完整的uri路径  com.mmk.provider/query
         * code:返回值
         */
        sURIMatcher.addURI("com.mmk.provider", "query", QUERYSECCEED);
        sURIMatcher.addURI("com.mmk.provider", "insert", INSERTSECCEED);
        sURIMatcher.addURI("com.mmk.provider", "update", UPDATESECCEED);
        sURIMatcher.addURI("com.mmk.provider", "delete", DELETESECCEED);
    }
    
    //初始化内容提供者 
    //在这里实例化数据库助手
    @Override
    public boolean onCreate() {
        helper = new MyOpenHelper(getContext());
        return false;
    }
    
    //[3]暴露自己想暴露的方法 (增删改查)
    //数据库的查询操作
    /*  Uri uri:要匹配的路径
     *  String[] projection:The list of columns to put into the cursor. If null all columns are included
     *  上面这行参数 要查询的列 null代表所有列
     *  String selection:查询的条件
     *  String[] selectionArgs:查询的条件的值
     *  String sortOrder:根据什么排序 null表示不排序
     * (non-Javadoc)
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        //判断路径是否匹配正确
        int code = sURIMatcher.match(uri);
        //匹配正确 实现查询操作
        if (code == QUERYSECCEED) {
            //对数据库的操作必须获取SQLiteDatabase实例
            SQLiteDatabase db = helper.getWritableDatabase();
            Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
            return cursor;
        } else {
            throw new IllegalArgumentException("你的路径匹配不正确");
        }
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    //暴露数据库的添加数据方法
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int code = sURIMatcher.match(uri);
        if (code == INSERTSECCEED) {//进行添加操作
            SQLiteDatabase db = helper.getWritableDatabase();
            //返回值:the row ID of the newly inserted row, or -1 if an error occurred
            //代表新插入的行的ID
            long insert = db.insert("info", null, values);
            //返回值是Uri类型  构建一个Uri对象
            Uri uri2 = Uri.parse("com.zhang.insert/"+insert);
            return uri2;
        } else {
            throw new IllegalArgumentException("你的路径不匹配");
        }
    }

    //暴露删除方法
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int code = sURIMatcher.match(uri);
        if (code == DELETESECCEED) {
            SQLiteDatabase db = helper.getWritableDatabase();
            //返回值 代表影响的行数
            int delete = db.delete("info", selection, selectionArgs);
            return delete;
        } else {
            throw new IllegalArgumentException("你的路径不匹配");
        }
    }

    //暴露更新方法
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        int code = sURIMatcher.match(uri);
        if (code == UPDATESECCEED) {
            SQLiteDatabase db = helper.getWritableDatabase();
            //返回值代表影响的行数
            int update = db.update("info", values, selection, selectionArgs);
            return update;
        } else {
            throw new IllegalArgumentException("你的路径不匹配");
        }
    }

}

5,如果在日志中打印一些内容 则说明内容提供者提供内容成功

6,新建工程 获取内容解析者 对上一个工程的数据库进行操作
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void clickUpdate(View v) {
    Uri uri = Uri.parse("content://com.mmk.provider/update");
    ContentValues values = new ContentValues();
    values.put("name", "杨子珊");
    int update = getContentResolver().update(uri, values, "name=?", new String[]{"zhang"});
    System.out.println(update);
}

public void clickDelete(View v) {
    Uri uri = Uri.parse("content://com.mmk.provider/delete");
    int delete = getContentResolver().delete(uri, "phone=?", new String[]{"1055"});
    System.out.println(delete);
}

public void clickAdd(View v) {
    Uri uri = Uri.parse("content://com.mmk.provider/insert");
    ContentValues values = new ContentValues();
    values.put("name", "zhang");
    values.put("phone", "123");
    Uri uri2 = getContentResolver().insert(uri, values);
    System.out.println(uri);
    System.out.println(uri2);
}

/**
 * 点击事件
 * 内容解析者解析上一个应用的数据
 * @param v
 */
public void clickQuery(View v) {
    //获取内容解析者实例
    ContentResolver resolver = getContentResolver();
    //读数据库进行操作
    //uri:uri The URI, using the content:// scheme, for the content to retrieve.
    Uri uri = Uri.parse("content://com.mmk.provider/query");
    Cursor cursor = resolver.query(uri, null, null, null, null);
    if (cursor != null && cursor.getCount() >= 0) {
        while (cursor.moveToNext()) {
            String name = cursor.getString(1);
            String phone = cursor.getString(2);
            System.out.println("name:"+name +" phone:"+phone);
        }
    }
    cursor.close();
}

}

注意:如果内容提供者中的而数据库改变了 在运行内容解析者工程之前 要先运行内容提供者工程

三:内容解析者获取手机中的联系人

1,来到这个路径下 到处该联系人数据库表

2,解读三张表

  • data表 data1这一列表示了所有联系人的所有信息

  • data表 raw_contact_id这一列 事实上就是 raw_contact表 中的 contact_id这一列

  • data表 mimetype列对应 mimetype表

3,读取手机联系人的步骤:

  • [1] 先读取raw_contact表 中的contact_id字段 从而知道一共有多少个联系人

  • [2]再读取data表 根据raw_contact_id字段读取data1字段和mimetype_id字段

看源码的步骤:

1,这个路径下的清单文件 找到



2,来到ContactsProvider2.java 文件下



示例代码:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getContacts();//获取手机联系人
    }

    /**
     * 获取手机联系人方法
     */
    private void getContacts() {
        //手机联系人数据库已经用内容提供者暴露出来 用该内容解析者来获取数据
        //[1]读取raw_contact表  查询contact_id字段  从而知道一共有多少联系人
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri dataUri = Uri.parse("content://com.android.contacts/data");
        Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
        if (cursor != null && cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                //这里的contact_id就是返回了当前手机联系人个数的id
                String contact_id = cursor.getString(0);
//              System.out.println("contact_id = "+contact_id);
                
                //[2]根据raw_contact_id字段查询    data表   中的data1字段和mimetype_id字段
//              Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1","mimetype_id"}, "raw_contact_id=?", new String[]{"contact_id"}, null);
                //注意了 这里查询的并不是data表  而是view_data表  而该表中没有mimetype_id字段 只有mimetype字段
                
                Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{contact_id}, null);
                if (dataCursor != null && dataCursor.getCount() > 0) {
                    while (dataCursor.moveToNext()) {
                        String data1 = dataCursor.getString(0);
                        String mimetype = dataCursor.getString(1);
//                      System.out.println("data1:"+data1 + " mimetype:"+mimetype);
                        
                        //根据mimetype来判断类型
                        if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
                            System.out.println("电话:"+data1);
                        } else if ("vnd.android.cursor.item/name".equals(mimetype)) {
                            System.out.println("姓名:"+data1);
                        }
                    }
                }
                
            }
        }
        
    }

}

相关文章

网友评论

      本文标题:Android_06 ContentProvider

      本文链接:https://www.haomeiwen.com/subject/fhneaqtx.html