安卓联系人

  ContentProvider

 

因为在Android系统里面,数据库是私有的。一般情况下外部应用程序是没有权限读取其他应用程序的数据。如果你想公开你自己的数据,你有两个选择:你可以创建你自己的内容提供器(一个ContentProvider子类)或者你可以给已有的提供器添加数据-如果存在一个控制同样类型数据的内容提供器且你拥有写的权限。而外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据,当然,中间也会涉及一些权限的问题。

 

而以下方法是需要在子类实现的:

1

2

3

4

5

6

7

8

9

10

11

boolean onCreate() Called when the provider is being started.  

   

Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) 通过Uri进行查询,返回一个Cursor。  

   

Uri insert(Uri url, ContentValues values) 将一组数据插入到Uri 指定的地方,返回新inserted的URI。  

   

int update(Uri uri, ContentValues values, String where, String[] selectionArgs) 更新Uri指定位置的数据,返回所影响的行数。  

   

int delete(Uri url, String where, String[] selectionArgs) 删除指定Uri并且符合一定条件的数据,返回所影响的行数。  

   

String getType (Uri uri) 获取所查询URI的MIME类型,如果没有类型则返回null

应用程序可以在Content Provider中执行如下操作:


查询数据

修改数据

添加数据

删除数据

当我们不需要把数据提供给第三方应用程序使用的话,可以不实现Content Provider。

 

 ContentResolver / getContentResolver()

 

 

外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。ContentResolver提供的接口和ContentProvider中需要实现的接口对应,具体可以查看API Doc,不过可以发现ContentResolver里面的方法很多都是final或者static的。在实际应用中,我们很少实现ContentResolver抽象类,更多时候通过getContentResolver()从一个Activity或其它应用程序组件的实现里获取一个ContentResolver

 

1

ContentResolver cr = getContentResolver();

 

然后你可以使用这个ContentResolver的方法来和你感兴趣的任何内容提供器交互。

当初始化一个查询时,Android系统识别查询目标的内容提供器并确保它正在运行。系统实例化所有的ContentProvider对象;你从来不需要自己做。事实上,你从来不会直接处理ContentProvider对象。通常,对于每个类型的ContentProvider只有一个简单的实例。但它能够和不同应用程序和进程中的多个ContentProvider对象通讯。进程间的交互通过ContentResolver和ContentProvider类处理。

 

 

 

查询记录:


        在Content Provider中使用的查询字符串有别于标准的SQL查询。很多诸如select, add, delete, modify等操作我们都使用一种特殊的URI来进行,这种URI由3个部分组成, “content://”, 代表数据的路径,和一个可选的标识数据的ID。以下是一些示例URI:


        content://media/internal/images  这个URI将返回设备上存储的所有图片
        content://contacts/people/  这个URI将返回设备上的所有联系人信息
        content://contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录)

        尽管这种查询字符串格式很常见,但是它看起来还是有点令人迷惑。为此,Android提供一系列的帮助类(在android.provider包下),里面包含了很多以类变量形式给出的查询字符串,这种方式更容易让我们理解一点,参见下例:

        MediaStore.Images.Media.INTERNAL_CONTENT_URI
        Contacts.People.CONTENT_URI

        因此,如上面content://contacts/people/45这个URI就可以写成如下形式:

        Uri person = ContentUris.withAppendedId(People.CONTENT_URI, 45);

        然后执行数据查询:

        Cursor cur = managedQuery(person, null, null, null);

        这个查询返回一个包含所有数据字段的游标,我们可以通过迭代这个游标来获取所有的数据:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

package com.wissen.testApp;         

                   

public class ContentProviderDemo extends Activity {         

    @Override         

    public void onCreate(Bundle savedInstanceState) {         

        super.onCreate(savedInstanceState);         

        setContentView(R.layout.main);         

       displayRecords();         

    }         

                   

    private void displayRecords() {         

        //该数组中包含了所有要返回的字段         

     String columns[] = new String[] { People.NAME, People.NUMBER };         

       Uri mContacts = People.CONTENT_URI;         

       Cursor cur = managedQuery(         

           mContacts,         

          columns,  // 要返回的数据字段         

       null,          // WHERE子句         

       null,         // WHERE 子句的参数         

       null         // Order-by子句         

     );         

       if (cur.moveToFirst()) {         

           String name = null;         

           String phoneNo = null;         

           do {         

              // 获取字段的值         

         name = cur.getString(cur.getColumnIndex(People.NAME));         

             phoneNo = cur.getString(cur.getColumnIndex(People.NUMBER));         

             Toast.makeText(this, name + ” ” + phoneNo, Toast.LENGTH_LONG).show();         

          } while (cur.moveToNext());         

       }         

    }         

}

 

        上例示范了一个如何依次读取联系人信息表中的指定数据列name和number。



修改记录:


        我们可以使用ContentResolver.update()方法来修改数据,我们来写一个修改数据的方法:

 

1

2

3

4

5

6

private void updateRecord(int recNo, String name) {          

    Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, recNo);          

    ContentValues values = new ContentValues();          

    values.put(People.NAME, name);          

    getContentResolver().update(uri, values, nullnull);          

}

 

        现在你可以调用上面的方法来更新指定记录:

        updateRecord(10, ”XYZ”); //更改第10条记录的name字段值为“XYZ”

 

添加记录:


        要增加记录,我们可以调用ContentResolver.insert()方法,该方法接受一个要增加的记录的目标URI,以及一个包含了新记录值的Map对象,调用后的返回值是新记录的URI,包含记录号。
        上面的例子中我们都是基于联系人信息簿这个标准的Content Provider,现在我们继续来创建一个insertRecord() 方法以对联系人信息簿中进行数据的添加:

1

2

3

4

5

6

7

8

9

10

11

private void insertRecords(String name, String phoneNo) {          

    ContentValues values = new ContentValues();          

    values.put(People.NAME, name);          

    Uri uri = getContentResolver().insert(People.CONTENT_URI, values);          

    Log.d(”ANDROID”, uri.toString());          

    Uri numberUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);          

    values.clear();          

    values.put(Contacts.Phones.TYPE, People.Phones.TYPE_MOBILE);          

    values.put(People.NUMBER, phoneNo);          

    getContentResolver().insert(numberUri, values);          

}

 

        这样我们就可以调用insertRecords(name, phoneNo)的方式来向联系人信息簿中添加联系人姓名和电话号码。


删除记录:


        Content Provider中的getContextResolver.delete()方法可以用来删除记录,下面的记录用来删除设备上所有的联系人信息:

 

1

2

3

4

private void deleteRecords() {          

    Uri uri = People.CONTENT_URI;          

    getContentResolver().delete(uri, nullnull);          

}

 

        你也可以指定WHERE条件语句来删除特定的记录:

        getContentResolver().delete(uri, “NAME=” + “‘XYZ XYZ’”, null);

        这将会删除name为‘XYZ XYZ’的记录。

 


你可能感兴趣的:(安卓)