【安卓】Content Provider 基础

Content Provider介绍Android中的Content Provider机制可以支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。在android系统中,没有一个公共的内存区域,供多个应用共享存储数据,要在多个应用中共享数据,就需要使用Content Provider。
Android提供了一些常用数据类型的Contentprovider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些android提供的Content Provider。
公开应用私有数据的两种方式1:创建自己的Content Provider,需要继承ContentProvider类,让其他应用来访问自己的Content Provider。
2:把自己的数据通过Content Provider添加到其他应用中去,这样所有的应用都可以通过那个Content Provider来访问这些数据。

所有Content Provider都需要实现相同的接口,通过这个接口来进行数据的增加、修改、删除和查询的功能。
要使用Content Provider是非常简单的,只需要获得ContentResolver对象,然后通过这个对象进行数据的CRUD操作。获得ContentResolver的方式如下:ContentResolver cr = getContentResolver();Android系统负责初始化所有的Content Provider,不需要用户自己去创建。实际上,Content Provider的用户都不可能直接访问到Content Provider实例,只能通过ContentResolver在中间代理。
Content Provider展示数据类似一个数据库的表。其中:每行有个值唯一的数字字段,名为_ID,可用于对表中指定记录的定位;Content Provider返回的数据结构,类似JDBC的ResultSet,在Android中,是Cursor对象。

理解URI1:每个Content Provider定义一个唯一的公开的URI,用于指定到它的数据集。一个Content Provider可以包含多个数据集,这样,就需要有多个URI与每个数据集相对应。
2:URI的格式,标准的格式分成了四个部分,示例如下:
content://     cn.javass.users     /students       /12
(1)content://:标准前缀,用来说明一个Content Provider控制这些数据
(2)cn.javass.users:URI的标识,它定义了是哪个Content Provider的实现来提供这些数据。为了保证URI标识的唯一性,它必须是一个完整的、小写的、ContentProvider实现类名。这个标识在<provider> 元素的 authorities属性中说明: <provider name=”.Users”  authorities=”cn.javass.users”>
(3)/students :路径,Content Provider用来确定当前需要什么类型的数据,URI中可能包括0到多个路径
(4)12:具体某条数据的标识,如果URI中包含,表示需要获取的记录的ID;如果没有ID,就表示返回全部。
ContentResolver的使用1:ContentResolver通过URI来操作ContentProvider提供的数据。因此你必须知道要操作数据的URI,除此之外,还必须知道要操作的数据段的名称,以及此数据段的数据类型。如果你想要获取一个特定的记录,你还必须知道此记录的ID
2: ContentResolver的常用方法是完全类似于数据库操作的,如下:
(1)新增:insert(Uri url, ContentValues values),返回Uri
(2)删除:delete(Uri url, String where, String[] selectionArgs),返回操作的记录条数
(3)修改:update(Uri uri, ContentValues values, String where, String[] selectionArgs) ,返回操作的记录条数
(4)查询:query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder),返回Cursor
创建自己的Content ProviderUriMatcher:用于匹配Uri,基本用法如下:1:注册能匹配的Uri
(1)常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
(2)如果match()方法匹配某个路径,设置一个返回的值。
例如匹配content://com.android.calendar/calendars路径,返回匹配码为1。uriMatcher.addURI(“content://com.android.calendar”, “calendars”, 1);
(3)如果match()方法匹配某个URI,设置一个返回的值。例如匹配
content://com.android.calendar/calendars/11这个URI,返回匹配码为2。uriMatcher.addURI(“content://com.android.calendar”, “calendars/#”, 2);
2:注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码。
ContentUris:用于操作Uri路径后面的ID部分,它有两个比较实用的方法:1:withAppendedId(uri, id)用于为路径加上ID部分
2:parseId(uri)方法用于从路径中获取ID部分
创建自己的Content Provider,基本步骤如下:1:写一个类继承ContentProvider,就需要实现相应的方法
2: Content Provider通常需要对外提供:CONTENT_URI、URI_AUTHORITY,对外的数据字段常量等,例如:

java代码:

  1. public static final String URI_AUTHORITY = "cn.javass.mycp";

  2. public static final String URI_PATH = "Users";
  3. public static final String URI_PATH2 = "Users/#";
  4. public static final Uri CONTENT_URI = Uri.parse("content://"
  5. + URI_AUTHORITY + "/" + URI_PATH);
  6. //对外的数据字段
  7. public static final String COLUMN_UUID = "uuid";
  8. public static final String COLUMN_NAME = "name";

复制代码

  1. public static final String URI_AUTHORITY = "cn.javass.mycp";
  2. public static final String URI_PATH = "Users";
  3. public static final String URI_PATH2 = "Users/#";
  4. public static final Uri CONTENT_URI = Uri.parse("content://"
  5. + URI_AUTHORITY + "/" + URI_PATH);
  6. //对外的数据字段
  7. public static final String COLUMN_UUID = "uuid";
  8. public static final String COLUMN_NAME = "name";

复制代码

3:提供UriMatcher,用来判断外部传入的Uri是否带有id,好区分处理:

  1. public static final int ALL_RECORDS = 1;

  2. public static final int SINGLE_RECORD = 2;
  3. public static UriMatcher sMatcher = null;
  4. static {
  5. sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  6. sMatcher.addURI(URI_AUTHORITY, URI_PATH, ALL_RECORDS);
  7. sMatcher.addURI(URI_AUTHORITY, URI_PATH2, SINGLE_RECORD);
  8. }

复制代码

  1. public static final int ALL_RECORDS = 1;
  2. public static final int SINGLE_RECORD = 2;
  3. public static UriMatcher sMatcher = null;
  4. static {
  5. sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  6. sMatcher.addURI(URI_AUTHORITY, URI_PATH, ALL_RECORDS);
  7. sMatcher.addURI(URI_AUTHORITY, URI_PATH2, SINGLE_RECORD);
  8. }

复制代码

然后就是根据自己保存数据的具体实现,来实现Content Provider的方法,这里以前面SQLite的示例来演示如何实现这些方法。
新增功能的简单实现
java代码:

  1. public Uri insert(Uri uri, ContentValues values) {

  2. Uri retUri = null;
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. //判断是否需要处理,只有符合的才处理
  5. SQLiteDatabase db = dh.getWritableDatabase();
  6. long id = db.insert("tbl_user",null, values);
  7. retUri = ContentUris.withAppendedId(uri, id);
  8. }
  9. return retUri;
  10. }

复制代码

  1. public Uri insert(Uri uri, ContentValues values) {
  2. Uri retUri = null;
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. //判断是否需要处理,只有符合的才处理
  5. SQLiteDatabase db = dh.getWritableDatabase();
  6. long id = db.insert("tbl_user",null, values);
  7. retUri = ContentUris.withAppendedId(uri, id);
  8. }
  9. return retUri;
  10. }

复制代码

查询功能的简单实现java代码:

  1. public Cursor query(Uri uri, String[] projection, String selection,

  2. String[] selectionArgs, String sortOrder) {
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. SQLiteDatabase db = dh.getWritableDatabase();
  5. Cursor c = db.query("tbl_user", projection,
  6. selection,selectionArgs, "", "", sortOrder,"");
  7. return c;
  8. }else if(sMatcher.match(uri)==SINGLE_RECORD){
  9. //这里应该处理带id的uri,省略了.....
  10. }
  11. return null;
  12. }

复制代码

  1. public Cursor query(Uri uri, String[] projection, String selection,
  2. String[] selectionArgs, String sortOrder) {
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. SQLiteDatabase db = dh.getWritableDatabase();
  5. Cursor c = db.query("tbl_user", projection,
  6. selection,selectionArgs, "", "", sortOrder,"");
  7. return c;
  8. }else if(sMatcher.match(uri)==SINGLE_RECORD){
  9. //这里应该处理带id的uri,省略了.....
  10. }
  11. return null;
  12. }

复制代码

修改功能的简单实现
java代码:

  1. public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {

  2. int ret = 0;
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. //判断是否需要处理,只有符合的才处理
  5. SQLiteDatabase db = dh.getWritableDatabase();
  6. ret = db.update("tbl_user",values,selection, selectionArgs);
  7. }else if(sMatcher.match(uri)==SINGLE_RECORD){//这里应该处理带id的uri,省略了.....}
  8. return ret;
  9. }

复制代码

  1. public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
  2. int ret = 0;
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. //判断是否需要处理,只有符合的才处理
  5. SQLiteDatabase db = dh.getWritableDatabase();
  6. ret = db.update("tbl_user",values,selection, selectionArgs);
  7. }else if(sMatcher.match(uri)==SINGLE_RECORD){//这里应该处理带id的uri,省略了.....}
  8. return ret;
  9. }

复制代码

删除功能的简单实现
java代码:

  1. public int delete(Uri uri, String selection, String[] selectionArgs) {

  2. int ret = 0;
  3. if(sMatcher.match(uri)==ALL_RECORDS){
  4. //判断是否需要处理,只有符合的才处理
  5. SQLiteDatabase db = dh.getWritableDatabase();
  6. ret = db.delete("tbl_user", selection, selectionArgs);
  7. }else if(sMatcher.match(uri)==SINGLE_RECORD){//这里应该处理带id的uri,省略了.....}
  8. return ret;
  9. }

复制代码

  1. [java] view plaincopy
  2. public int delete(Uri uri, String selection, String[] selectionArgs) {
  3. int ret = 0;
  4. if(sMatcher.match(uri)==ALL_RECORDS){
  5. //判断是否需要处理,只有符合的才处理
  6. SQLiteDatabase db = dh.getWritableDatabase();
  7. ret = db.delete("tbl_user", selection, selectionArgs);
  8. }else if(sMatcher.match(uri)==SINGLE_RECORD){//这里应该处理带id的uri,省略了.....}
  9. return ret;
  10. }

复制代码

getType的简单实现,getType方法返回数据的MIME typejava代码:

  1. public String getType(Uri uri) {

  2. switch (sMatcher.match(uri)) {
  3. case ALL_RECORDS:
  4. return "vnd.android.cursor.dir/vnd.cn.javass.users";
  5. case SINGLE_RECORD:
  6. return "vnd.android.cursor.item/vnd.cn.javass.users";
  7. default:
  8. throw new IllegalArgumentException("unknown URI " + uri);
  9. }
  10. }

复制代码

  1. public String getType(Uri uri) {
  2. switch (sMatcher.match(uri)) {
  3. case ALL_RECORDS:
  4. return "vnd.android.cursor.dir/vnd.cn.javass.users";
  5. case SINGLE_RECORD:
  6. return "vnd.android.cursor.item/vnd.cn.javass.users";
  7. default:
  8. throw new IllegalArgumentException("unknown URI " + uri);
  9. }
  10. }

复制代码

onCreate方法的简单实现
java代码

  1. public boolean onCreate() {

  2. if (mContext == null) {mContext = this.getContext();}
  3. if(dh==null){
  4. dh = new DBHelper(mContext,"testDB1",null,1);
  5. }
  6. return true;
  7. }

复制代码

  1. public boolean onCreate() {
  2. if (mContext == null) {mContext = this.getContext();}
  3. if(dh==null){
  4. dh = new DBHelper(mContext,"testDB1",null,1);
  5. }
  6. return true;
  7. }

复制代码

使用自己的Content Provider有了自己实现的Content Provider后,要使用就很简单了。首先要在AndroidManifest.xml文件中注册自己的Content Provider,示例如下:
java代码:

  1. <provider android:name=".MyCP"

  2. android:authorities="cn.javass.mycp"></provider>
  3. [java] view plaincopy
  4. <provider android:name=".MyCP"
  5. android:authorities="cn.javass.mycp"></provider>

复制代码

使用新增的功能,先示范单条新增:
java代码:

  1. ContentValues values = new ContentValues();

  2. values.put(MyCP.COLUMN_UUID, "test1");
  3. values.put(MyCP.COLUMN_NAME,"cc1");
  4. Uri uri = getContentResolver().insert(MyCP.CONTENT_URI, values);
  5. [java] view plaincopy
  6. ContentValues values = new ContentValues();
  7. values.put(MyCP.COLUMN_UUID, "test1");
  8. values.put(MyCP.COLUMN_NAME,"cc1");
  9. Uri uri = getContentResolver().insert(MyCP.CONTENT_URI, values);

复制代码

还可以使用批处理的方式来使用新增的功能,示例如下:
java代码:查看

  1. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

  2. ops.add(ContentProviderOperation.newInsert(MyCP.CONTENT_URI)
  3. .withValue(MyCP.COLUMN_UUID, "test2")
  4. .withValue(MyCP.COLUMN_NAME, "cc2")
  5. .build());
  6. ops.add(ContentProviderOperation.newInsert(MyCP.CONTENT_URI)
  7. .withValue(MyCP.COLUMN_UUID, "test3")
  8. .withValue(MyCP.COLUMN_NAME, "cc3")
  9. .build());
  10. try {
  11. getContentResolver().applyBatch(MyCP.URI_AUTHORITY,ops);
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. }

复制代码

  1. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  2. ops.add(ContentProviderOperation.newInsert(MyCP.CONTENT_URI)
  3. .withValue(MyCP.COLUMN_UUID, "test2")
  4. .withValue(MyCP.COLUMN_NAME, "cc2")
  5. .build());
  6. ops.add(ContentProviderOperation.newInsert(MyCP.CONTENT_URI)
  7. .withValue(MyCP.COLUMN_UUID, "test3")
  8. .withValue(MyCP.COLUMN_NAME, "cc3")
  9. .build());
  10. try {
  11. getContentResolver().applyBatch(MyCP.URI_AUTHORITY,ops);
  12. } catch (Exception e) {
  13. e.printStackTrace();
  14. }

复制代码

使用查询的功能:
java代码:

  1. Cursor c = getContentResolver().query(MyCP.CONTENT_URI,

  2. new String[] {MyCP.COLUMN_UUID, MyCP.COLUMN_NAME}, null,null, null);
  3. while (c.moveToNext()) {
  4. String dId = ""+c.getString(c.getColumnIndex(MyCP.COLUMN_UUID));
  5. String name = c.getString(c.getColumnIndex(MyCP.COLUMN_NAME));
  6. Log.i("now query","dataId="+dId+",name="+name);
  7. }

复制代码

  1. Cursor c = getContentResolver().query(MyCP.CONTENT_URI,
  2. new String[] {MyCP.COLUMN_UUID, MyCP.COLUMN_NAME}, null,null, null);
  3. while (c.moveToNext()) {
  4. String dId = ""+c.getString(c.getColumnIndex(MyCP.COLUMN_UUID));
  5. String name = c.getString(c.getColumnIndex(MyCP.COLUMN_NAME));
  6. Log.i("now query","dataId="+dId+",name="+name);
  7. }

复制代码

使用修改的功能,这里只示例单条的处理,批处理的方式参见前面新增的实现:
java代码:

  1. ContentValues values = new ContentValues();

  2. values.put(MyCP.COLUMN_UUID, "test1");
  3. values.put(MyCP.COLUMN_NAME,"cc1update");
  4. getContentResolver().update(MyCP.CONTENT_URI, values,MyCP.COLUMN_UUID+"=?",new String[]{"test1"});

复制代码

  1. ContentValues values = new ContentValues();
  2. values.put(MyCP.COLUMN_UUID, "test1");
  3. values.put(MyCP.COLUMN_NAME,"cc1update");
  4. getContentResolver().update(MyCP.CONTENT_URI, values,MyCP.COLUMN_UUID+"=?",new String[]{"test1"});

复制代码

使用删除的功能:

  1. getContentResolver().delete(MyCP.CONTENT_URI, MyCP.COLUMN_UUID + "=?",new String[] { "test2" });

复制代码

  1. getContentResolver().delete(MyCP.CONTENT_URI, MyCP.COLUMN_UUID + "=?",new String[] { "test2" });

复制代码

几点说明1:这里创建的自己的Content Provider是非常简单的,主要是沿用了前面SQLite的示例,当然也可以使用文件操作的示例
2:一般来说,提供Content Provider的数据,应该有一个long型的id字段,由于前面的示例没有,所以上面的示例没有提供
3:在自己的Content Provider实现里面,应该根据Uri是否带有id的情况进行相应的处理,为了示例的简单,就没有那么实现了
4:由于Content Provider可能被多个应用同时使用,因此需要在实现Content Provider的时候进行多线程控制,目前并没有实现这样的功能
5:处理多线程的一个好方式就是,当数据发生改变的时候,通知所有相关的数据改变,比如在新增、修改、删除方法里面提供:

java代码:

  1. getContext().getContentResolver().notifyChange(Uri, null);

复制代码

  1. getContext().getContentResolver().notifyChange(Uri, null);

复制代码

操作通讯录要使用其他应用提供的Content Provider是非常简单的,只需要获取ContentResolver对象,然后使用它的方法操作数据即可。
这里以最常见的功能:操作通讯录 为例来示范如何使用Content Provider。
记得添加操作Contacts需要的权限

java代码:

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

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

复制代码

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

复制代码

先看看新增的功能实现,先以单独操作的方式来示范:
java代码:

  1. //1:添加原始的帐号信息

  2. ContentValues values = new ContentValues();
  3. values.put(RawContacts.ACCOUNT_TYPE, "userAccount");
  4. values.put(RawContacts.ACCOUNT_NAME, "cc");
  5. Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);
  6. long rawContactId = ContentUris.parseId(rawContactUri);
  7. //2:添加账户人员的姓名
  8. values.clear();
  9. values.put(Data.RAW_CONTACT_ID, rawContactId);
  10. values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
  11. values.put(StructuredName.DISPLAY_NAME, "cc1Name");
  12. getContentResolver().insert(Data.CONTENT_URI, values);

复制代码

  1. //1:添加原始的帐号信息
  2. ContentValues values = new ContentValues();
  3. values.put(RawContacts.ACCOUNT_TYPE, "userAccount");
  4. values.put(RawContacts.ACCOUNT_NAME, "cc");
  5. Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);
  6. long rawContactId = ContentUris.parseId(rawContactUri);
  7. //2:添加账户人员的姓名
  8. values.clear();
  9. values.put(Data.RAW_CONTACT_ID, rawContactId);
  10. values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
  11. values.put(StructuredName.DISPLAY_NAME, "cc1Name");
  12. getContentResolver().insert(Data.CONTENT_URI, values);

复制代码

java代码:

  1. //3:添加电话信息

  2. values.clear();
  3. values.put(Data.RAW_CONTACT_ID, rawContactId);
  4. values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  5. values.put(Phone.NUMBER, "13567890987");
  6. values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
  7. values.put(Phone.LABEL, "cc1");
  8. Uri dataUri = getContentResolver().insert(Data.CONTENT_URI,values);
  9. //同理,还可以添加Email等等信息

复制代码

  1. //3:添加电话信息
  2. values.clear();
  3. values.put(Data.RAW_CONTACT_ID, rawContactId);
  4. values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  5. values.put(Phone.NUMBER, "13567890987");
  6. values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
  7. values.put(Phone.LABEL, "cc1");
  8. Uri dataUri = getContentResolver().insert(Data.CONTENT_URI,values);
  9. //同理,还可以添加Email等等信息

复制代码

新增的功能实现,以批处理操作的方式来示范:前面第一步,添加原始的帐号信息的过程是一样的,批处理最好用在后面都是对Data进行操作的过程中,示例如下:

java代码:

  1. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

  2. ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
  3. .withValue(Data.RAW_CONTACT_ID, rawContactId)
  4. .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
  5. .withValue(StructuredName.DISPLAY_NAME, "cc1Name")
  6. .build());
  7. ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
  8. .withValue(Data.RAW_CONTACT_ID, rawContactId)
  9. .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
  10. .withValue(Phone.NUMBER, "13567890989")
  11. .withValue(Phone.TYPE, Phone.TYPE_CUSTOM)
  12. .withValue(Phone.LABEL, "cc1").build());
  13. try {
  14. getContentResolver().applyBatch(ContactsContract.AUTHORITY,ops);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }

复制代码

  1. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  2. ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
  3. .withValue(Data.RAW_CONTACT_ID, rawContactId)
  4. .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
  5. .withValue(StructuredName.DISPLAY_NAME, "cc1Name")
  6. .build());
  7. ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
  8. .withValue(Data.RAW_CONTACT_ID, rawContactId)
  9. .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
  10. .withValue(Phone.NUMBER, "13567890989")
  11. .withValue(Phone.TYPE, Phone.TYPE_CUSTOM)
  12. .withValue(Phone.LABEL, "cc1").build());
  13. try {
  14. getContentResolver().applyBatch(ContactsContract.AUTHORITY,ops);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }

复制代码

查询功能的实现,示例如下:
java代码:

  1. //1:得到要操作的原始帐号信息

  2. Cursor c = getContentResolver().query(RawContacts.CONTENT_URI,
  3. new String[]{RawContacts._ID},RawContacts.ACCOUNT_NAME+"=? ",new String[]{"cc"}, null);
  4. long rawContactId = 0L;
  5. while(c.moveToNext()){
  6. rawContactId = c.getLong(c.getColumnIndex(RawContacts._ID));
  7. }
  8. c.close();
  9. //然后开始获取你需要的数据,这里示范读取电话数据,同理可以读取其他的数据,如Email数据
  10. c = getContentResolver().query(Data.CONTENT_URI,
  11. new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
  12. Data.RAW_CONTACT_ID+"=?"+" and "+Data.MIMETYPE + "=‘" + Phone.CONTENT_ITEM_TYPE + "‘",
  13. new String[]{""+rawContactId}, null);
  14. while (c.moveToNext()) {
  15. String dId = ""+c.getInt(c.getColumnIndex(Data._ID));
  16. String name = c.getString(c.getColumnIndex(Phone.LABEL));
  17. String num = c.getString(c.getColumnIndex(Phone.NUMBER));
  18. String type = c.getString(c.getColumnIndex(Phone.TYPE));
  19. Log.i("now query","dataId="+dId+",name="+name+",name="+num+", type="+type);
  20. }

复制代码

  1. //1:得到要操作的原始帐号信息
  2. Cursor c = getContentResolver().query(RawContacts.CONTENT_URI,
  3. new String[]{RawContacts._ID},RawContacts.ACCOUNT_NAME+"=? ",new String[]{"cc"}, null);
  4. long rawContactId = 0L;
  5. while(c.moveToNext()){
  6. rawContactId = c.getLong(c.getColumnIndex(RawContacts._ID));
  7. }
  8. c.close();
  9. //然后开始获取你需要的数据,这里示范读取电话数据,同理可以读取其他的数据,如Email数据
  10. c = getContentResolver().query(Data.CONTENT_URI,
  11. new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
  12. Data.RAW_CONTACT_ID+"=?"+" and "+Data.MIMETYPE + "=‘" + Phone.CONTENT_ITEM_TYPE + "‘",
  13. new String[]{""+rawContactId}, null);
  14. while (c.moveToNext()) {
  15. String dId = ""+c.getInt(c.getColumnIndex(Data._ID));
  16. String name = c.getString(c.getColumnIndex(Phone.LABEL));
  17. String num = c.getString(c.getColumnIndex(Phone.NUMBER));
  18. String type = c.getString(c.getColumnIndex(Phone.TYPE));
  19. Log.i("now query","dataId="+dId+",name="+name+",name="+num+", type="+type);
  20. }

复制代码

修改功能的实现,示例如下:
java代码:

  1. //1:应该要先得到要修改的Data数据,这里为了示范简单,就直接改了

  2. //2:设置修改的值
  3. ContentValues values = new ContentValues();
  4. values.put(Data.RAW_CONTACT_ID, 3);//测试时的数据是3
  5. values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  6. values.put(Phone.NUMBER, “13567890981”);//修改了
  7. values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
  8. values.put(Phone.LABEL, “upuser1”);//修改了
  9. getContentResolver().update(Data.CONTENT_URI, values,
  10. Data._ID + "=?",
  11. new String[] { “31” });//测试时的id是31

复制代码

  1. //1:应该要先得到要修改的Data数据,这里为了示范简单,就直接改了
  2. //2:设置修改的值
  3. ContentValues values = new ContentValues();
  4. values.put(Data.RAW_CONTACT_ID, 3);//测试时的数据是3
  5. values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  6. values.put(Phone.NUMBER, “13567890981”);//修改了
  7. values.put(Phone.TYPE, Phone.TYPE_CUSTOM);
  8. values.put(Phone.LABEL, “upuser1”);//修改了
  9. getContentResolver().update(Data.CONTENT_URI, values,
  10. Data._ID + "=?",
  11. new String[] { “31” });//测试时的id是31

复制代码

修改也可以使用批处理的功能来实现,可以参考前面新增的批处理实现。
删除功能的实现,示例如下:
java代码:

  1. //1:应该要先得到要删除的Data数据,这里为了示范简单,就直接改了

  2. //2:删除数据,直接删除原始的内容
  3. getContentResolver().delete(RawContacts.CONTENT_URI, Data._ID + "=?",
  4. new String[] { "31" });

复制代码

  1. //1:应该要先得到要删除的Data数据,这里为了示范简单,就直接改了
  2. //2:删除数据,直接删除原始的内容
  3. getContentResolver().delete(RawContacts.CONTENT_URI, Data._ID + "=?",
  4. new String[] { "31" });

复制代码

  1. 只要删除了原始的帐号数据,那么所有与它附属的数据,比如电话、Email等都会被自动删除。如果一个Contact对应的所有原始帐号数据都被删除掉了,那么Contact会被自动删除掉。
时间: 2024-10-30 11:50:51

【安卓】Content Provider 基础的相关文章

Android开发-API指南-Content Provider基础

Content Provider Basics 英文原文:http://developer.android.com/guide/topics/providers/content-provider-basics.html 采集日期:2015-01-07 在本文中 概述 访问 Provider Content URI 从 Content Provider 读取数据 申请读取权限 建立查询请求 显示查询结果 从查询结果中获取数据 Content Provider 相关权限 插入.修改.删除数据 插入数

Android开发-API指南-Content Provider

Content Providers 英文原文:http://developer.android.com/guide/topics/providers/content-providers.html 采集日期:2015-01-07 文章目录 Content Provider 基础 创建 Content Provider Calendar Provider Contact Provider 相关示例 Contact Manager 应用 “游标(联系人)” “游标(电话)” Sync Adapter

安卓开发_深入理解Content Provider

一.Content Provider概述 Content Provider用于保存和获取数据,并使其对所有应用程序可见,这是不同应用程序之间共享数据的唯一方式,因为在Android中没有提供所有应用可以共同访问的公共存储区域 1.  Content Provider内部的数据如何保存是由其设计者决定的,而所有的的Content Provider都实现一组通用的方法,用来提供数据的增删改查操作 2.  客户端如果要使用这些操作方法,可以通过ContentProvider对象实现对 Content

安卓学习之数据共享、内容提供器Content Provider

内容提供器Content Provider 能够实现不同程序之间内容的共享.安卓提供了这样的一套机制,让一个程序访问另一个程序的数据,同时保证了安全性. 一个程序可以通过内容提供器对其数据提供外部访问接口,这样其它程序就能通过接口来访问数据. ContentResolver 首先我们先介绍这个类.如果想要访问数据提供器中的数据,我们需要借助ContentResolver类.该对象实例可以在Context中调用getContentResolver()方法来获得.ContentResolver中提供

内容提供者基础 Content Provider Basics——翻译自developer.android.com

#内容提供者基础 Content Provider Basics content provicer 管理着中心数据仓库的访问.一个provider是Android的应用的一部分,它可以提供数据工作的UI. 然而,content provider基本都是被其他的应用访问,使用一个provider客户端对象来访问provider.provider和provider client一同创立了一个持续的标准的数据接口,它可以提供进程内通信以及安全数据访问. 这个主题讲解下面内容的基础部分: - conte

Android Studio开发基础之Content Provider组件

Content Provider是一个提供数据共享的组件,它主要将一些特定的应用程序数据提供给其他应用程序使用,这些应用程序数据可以存储于文件系统或者SQLite数据库中.在Android应用程序中,共享数据的实现需要继承自Content Provider基类,然而,应用程序并不直接调用这些方法,而是使用一个ContentResolver对象,并通过调用它的方法作为替代,ContentResolver对象提供了query,insert及update等方法,可以对共享的数据执行各种操作. 举例:使

android 基础一 &lt;Content Provider&gt;

第一步:定义类继承 ContentProvider,实现相关接口 public class MyContentProvider extends ContentProvider 第二步:定义 UriMatcher private final static String AUTHORITY="com.myprovider";//配置文件需要用到这个 private final static int INSERT_CODE=1; private final static int UPDATE

Android应用程序组件Content Provider简要介绍和学习计划

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6946067 在Android系统中,Content Provider作为应用程序四大组件之一,它起到在应用程序之间共享数据的作用,同时,它还是标准的数据访问接口.前面的一系列文章已经分析过 Android应用程序的其它三大组件(Activity.Service和Broadcast Receiver)了,本文将简要介绍Content Provid

Android应用程序组件Content Provider在应用程序之间共享数据的原理分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用程序是不能直接读写对方的数据文件的,如果它们想共享数据的话,只能通过 Content Provider组件来实现.那么,Content Provider组件又是如何突破应用程序边界权限控制来实现在不同的应用程序之间共享数据的呢?在前面的文章中,我们已经简要介绍过它是通过 Binder进程间通信机制以