Android内容提供器——现有内容提供器

不同程序之间想要获取数据需要用到的即使内容提供器来提供数据,而现有内容提供器可以提供给其他程序一些所需要的数据,如果想访问这些数据,则程序中需要通过context获得实例,借助ContentResolver类,其中提供了一系列的增删改查的方法。

内容提供器的操作和内置数据库SQLite的操作很像,不同的是传入参数时,数据库一般第一个参数传入的是表名,表示对那张表进行操作。而内容提供器传入的是Uri对象。

 

Uri对象获取:

  1.内容URI标准写法是:协议声明 content://  +  程序包名.provider  +  表名path 

如: 可以准确的表明需要访问哪个程序的哪张表。

content://com.example.app.provider/table1

  2.得到内容URI字符串,将其解析为URI对象:

Uri uri = Uri.parse("content://com.example.app.provider/table1")

 

ContentResolver类增删改查方法使用:

  1.查query():

 1 //query传入五个参数,分别是uri,查询的列名,指定where约束条件,where约束具体内容,指定查询结果的排序方式。
 2 Cursor cursor = getContentResolver().query(
 3     uri,projection,selection,selectionArgs,sortOrder);
 4 
 5 //返回的是一个Cursor对象,通过移动游标来遍历所有行,读出每行对应的数据。
 6 if (cursor != null) {
 7     while (cursor.moveToNext()) {
 8         String column1 = cursor.getString(cursor.getColumnIndex("column1"));
 9         int column2 = cursor.getInt(cursor.getColumnIndex("column2")); 
10     }
11     cursor.close();
12 }

  2.增加insert():

1 //先将数据封装到ContentValues中,然后用insert()方法传入相关参数
2 
3 ContentValues values = new ContentValues();
4 values.put("column1","text");
5 values.put("column2","1");
6 getContentResolver().insert(uri,values);

  3.更新Update():

1 //更新数据,将column1的值清空 update传入四个参数,后两个同样是where和对应的数据
2 ContentValues values = new ContentValues();
3 values.put("column1","");
4 getContentResolver().update(uri,values,"column1=?and column2=?",new String[]{"text","1"});

  4.删除delete():

getContentResolver().delete(uri,"column2 = ?",new String[]{"1"});

 

 

下面以程序要获取电话本数据为例:

1.布局文件

建立一个listview的布局文件:

 1 <LinearLayout xmlns:andorid="http://schemas.android.com/apk/res/android"
 2     andorid:layout_width="match_parent"
 3     andorid:layout_height="match_parent"
 4     andorid:orientation="vertical">
 5 
 6     <ListView
 7         andorid:id="@+id/contacts_view"
 8         andorid:layout_width="match_parent"
 9         andorid:layout_height="match_parent">
10 
11     </ListView>
12 </LinearLayout>

2.权限声明

因为用到了电话本的权限,所以先在AndroidManifest.xml中声明对应权限:

    <uses-permission android:name="android.permission.READ_CONTACTS"/>

3.主函数中Listview以及适配器  以及权限申请

先声明适配器和内容提供的格式,设置好listview的适配器。

判断用户是否有相应的读取通讯录的权限,如果有直接执行readContacts(),如果没有则想用户申请权限。

 1     ArrayAdapter<String> adapter;
 2     List<String> contactsList = new ArrayList<>();
 3 
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8 
 9         ListView contactsView = (ListView) findViewById(R.id.contacts_view);
10         /*适配器,三项参数分别是:context上下文,子项的布局
11         (下面用的是一个内置布局,只显示一段text),和要传入展示的内容*/
12         adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
13         contactsView.setAdapter(adapter);
14 
15         if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
16                 != PackageManager.PERMISSION_GRANTED) {
17             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
18         } else {
19             readContacts();
20         }
21     }

4.读取联系人

如果用户授权了相应的权限,则进行readContacts()方法。其中即是内容提供器中的查询方法。

需要注意的是,这里的uri对象没有使用内容uri再通过parse解析,而是直接用了一个 ContactsContract.CommonDataKinds.Phone.CONTENT_URI。这是ContactsContract.CommonDataKinds.Phone类已经将uri做好了封装,封装成了一个常量。同样下面的联系人姓名和电话,都是这个类进行封装好的量。

将数据查询取出到cursor之后,对cursor进行遍历,将姓名和电话数据进行拼接传入到listview的数据源中,并通知刷新一下listview。最后关闭cursor。

 1     private void readContacts() {
 2         Cursor cursor = null;
 3         try {
 4             /*查询联系人*/
 5             cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
 6                     null,null,null,null);
 7             if (cursor != null) {
 8                 while (cursor.moveToNext()) {
 9                     //获取联系人姓名
10                     String dispalyName = cursor.getString(cursor.getColumnIndex
11                             (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
12                     //获取联系人电话
13                     String number = cursor.getString(cursor.getColumnIndex
14                             (ContactsContract.CommonDataKinds.Phone.NUMBER));
15                     contactsList.add(dispalyName + "\n" + number);
16                 }
17                 adapter.notifyDataSetChanged();
18             }
19         } catch (Exception e) {
20             e.printStackTrace();
21         } finally {
22             if (cursor != null) {
23                 cursor.close();
24             }
25         }
26     }

5.requestPermissions的回调方法:

 1     @Override
 2     public void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults){
 3         switch (requestCode){
 4             case 1:
 5                 if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
 6                     readContacts();
 7                 }else {
 8                     Toast.makeText(this,"没有获得授权",Toast.LENGTH_LONG).show();
 9                 }
10                 break;
11             default:
12         }
13     }

 

posted @ 2018-08-24 15:54  Mask_D  阅读(489)  评论(0编辑  收藏  举报