内容提供器(Content Provider)


简介

替代文件存储和SharedPreferences存储中提供的MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE 这两种操作模式

主要用于在不同的应用程序之间实现数据共享的功能,可以保证被访数据的安全性。


ContentResolver

借助ContentResolve 类访问内容提供器中共享的数据。

通过Context 中的getContentResolver()方法获取到该类的实例。


CRUD:

insert()、query()、update()、delete()


内容URI 最标准的格式写法如下:
content://com.example.app.provider/table1    //包名.provider(表示权限)/表名(即某程序的数据库表)


1. 获取URI对象:

Uri uri = Uri.parse("content://com.example.app.provider/table1")    //Uri.parse()将URI字符串解析为Uri对象,通过该对象可以查询table1的数据

2. 查询table1表中的数据,query()方法查询完成后返回的仍然是一个Cursor 对象。

query()方法的参数说明
query()方法参数 对应SQL 部分 描述
uri from table_name 指定查询某个应用程序下的某一张表
projection select column1, column2 指定查询的列名
selection where column = value 指定where 的约束条件
selectionArgs - 为where 中的占位符提供具体的值
orderBy order by column1, column2 指定查询结果的排序方式


Cursor cursor = getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);  //获取游标ContentResolver实例并查询表,返回游标Cursor对象

3. 将数据从Cursor 对象中逐个读取出来,通过移动游标的位置来遍历Cursor 的所有行,然后再取出每一行中相应列的数据

if (cursor != null) {
    while (cursor.moveToNext()) {
        String column1 = cursor.getString(cursor.getColumnIndex("column1"));
        int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
    }
    cursor.close();
}

4. 向table1表添加数据

ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);

5. 更新数据,把column1 的值清空

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[] {"text", "1"});


6. 删除数据
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });


获取系统联系人数据


要求:获取系统联系人数据,并展示在程序的ListView中

布局:


MainActivity.java

public class MainActivity extends AppCompatActivity {
    ListView lvContacts;
    ArrayAdapter adapter;
    List list = new ArrayList();    //数据源,存储联系人数据

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvContacts = (ListView) findViewById(R.id.lv_contacts);
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
        lvContacts.setAdapter(adapter);
        readContacts(); //创建读取联系人方法
    }

    private void readContacts() {
        Cursor cursor = null;
        try {   //此处不要try-catch-finally 对结果显示不影响,为什么要?
            cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);    //获取游标ContentResolver实例并查询表(联系人),返回游标Cursor对象
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); //解析出的联系人姓名
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));     //解析出的联系人电话
                list.add(name + "\n" + number); //将数据添加进集合
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {   //当游标(即查询的结果)不为空时
                cursor.close(); //关闭游标
            }
        }
    }
}

上面cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI①, null, null, null, null);
此处①即Uri uri = Uri.parse("content://com.example.app.provider/table1") 中类似的uri,此处已经封装解析好成一个常量。


在AndroidManifest.xml配置读取联系人的权限


内容提供器(Content Provider)_第1张图片


创建内容提供器

P276


你可能感兴趣的:(2018.5.22以前)