ContentProvider(内容提供者)是Android中的四大组件之一。主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。ContentProvider分为系统的和自定义的,系统的也就是例如联系人,图片等数据。

以下这段是Google Doc中对ContentProvider的大致概述。
内容提供者将一些特定的应用程序数据供给其它应用程序使用。数据可以存储于文件系统、SQLite数据库或其它方式。内容提供者继承于ContentProvider 基类,为其它应用程序取用和存储它管理的数据实现了一套标准方法。然而,应用程序并不直接调用这些方法,而是使用一个 ContentResolver 对象,调用它的方法作为替代。ContentResolver可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理。

1.ContentProvider
Android提供了一些主要数据类型的ContentProvider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些Android提供的ContentProvider。通过获得这些ContentProvider可以查询它们包含的数据,当然前提是已获得适当的读取权限。
主要方法:
public boolean onCreate() 在创建ContentProvider时调用
public Cursor query(Uri, String[], String, String[], String) 用于查询指定Uri的ContentProvider,返回一个Cursor
public Uri insert(Uri, ContentValues) 用于添加数据到指定Uri的ContentProvider中
public int update(Uri, ContentValues, String, String[]) 用于更新指定Uri的ContentProvider中的数据
public int delete(Uri, String, String[]) 用于从指定Uri的ContentProvider中删除数据
public String getType(Uri) 用于返回指定的Uri中的数据的MIME类型
*如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
例如:要得到所有person记录的Uri为content://contacts/person,那么返回的MIME类型字符串为"vnd.android.cursor.dir/person"。
*如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
例如:要得到id为10的person记录的Uri为content://contacts/person/10,那么返回的MIME类型字符串应为"vnd.android.cursor.item/person"。

2.ContentResolver
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成,要获取ContentResolver对象,可以使用Context提供的getContentResolver()方法。

view plain copy to clipboard print ?
  1. ContentResolvercr=getContentResolver();

ContentResolver提供的方法和ContentProvider提供的方法对应的有以下几个方法。
public Uri insert(Uri uri, ContentValues values) 用于添加数据到指定Uri的ContentProvider中。
public int delete(Uri uri, String selection, String[] selectionArgs) 用于从指定Uri的ContentProvider中删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 用于更新指定Uri的ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 用于查询指定Uri的ContentProvider。

3.Uri
Uri指定了将要操作的ContentProvider,其实可以把一个Uri看作是一个网址,我们把Uri分为三部分。
第一部分是"content://"。可以看作是网址中的"http://"。
第二部分是主机名或authority,用于唯一标识这个ContentProvider,外部应用需要根据这个标识来找到它。可以看作是网址中的主机名,比如"blog.csdn.net"。
第三部分是路径名,用来表示将要操作的数据。可以看作网址中细分的内容路径。


// 查找sdcard卡上的所有歌曲信息
public List<Map<String, Object>> getMultiData() {
ArrayList<Map<String, Object>> musicList = new ArrayList<Map<String, Object>>();

// 加入封装音乐信息的代码
// 查询所有歌曲
ContentResolver musicResolver = this.getContentResolver();
Cursor musicCursor = musicResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
null);

int musicColumnIndex;

if (null != musicCursor && musicCursor.getCount() > 0) {
for (musicCursor.moveToFirst(); !musicCursor.isAfterLast(); musicCursor
.moveToNext()) {
Map<String, Object> musicDataMap = new HashMap<String, Object>();

Random random = new Random();
int musicRating = Math.abs(random.nextInt()) % 10;

musicDataMap.put("musicRating", musicRating);

// 取得音乐播放路径
musicColumnIndex = musicCursor
.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
musicPath = musicCursor.getString(musicColumnIndex);
musicDataMap.put("musicPath", musicPath);

// 取得音乐的名字
musicColumnIndex = musicCursor
.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE);
musicName = musicCursor.getString(musicColumnIndex);
musicDataMap.put("musicName", musicName);

// 取得音乐的专辑名称
musicColumnIndex = musicCursor
.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM);
musicAlbum = musicCursor.getString(musicColumnIndex);
musicDataMap.put("musicAlbum", musicAlbum);

// 取得音乐的演唱者
musicColumnIndex = musicCursor
.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST);
musicArtist = musicCursor.getString(musicColumnIndex);
musicDataMap.put("musicArtist", musicArtist);

// 取得歌曲对应的专辑对应的Key
musicColumnIndex = musicCursor
.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM_KEY);
musicAlbumKey = musicCursor.getString(musicColumnIndex);

String[] argArr = { musicAlbumKey };
ContentResolver albumResolver = this.getContentResolver();
Cursor albumCursor = albumResolver.query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, null,
MediaStore.Audio.AudioColumns.ALBUM_KEY + " = ?",
argArr, null);

if (null != albumCursor && albumCursor.getCount() > 0) {
albumCursor.moveToFirst();
int albumArtIndex = albumCursor
.getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM_ART);
musicAlbumArtPath = albumCursor.getString(albumArtIndex);
if (null != musicAlbumArtPath
&& !"".equals(musicAlbumArtPath)) {
musicDataMap.put("musicAlbumImage", musicAlbumArtPath);
} else {
musicDataMap.put("musicAlbumImage",
"file:///mnt/sdcard/alb.jpg");
}
} else {
// 没有专辑定义,给默认图片
musicDataMap.put("musicAlbumImage",
"file:///mnt/sdcard/alb.jpg");
}
musicList.add(musicDataMap);
}
}
return musicList;
}

下面是用ContentProvider读取联系人数据,属于系统数据。完整代码下载:android_contentprovider_system.rar

注意:这里的联系人操作有点乱,关键是我还不是很熟,SDK1.6和SDK2.1的联系人操作很有很大不同,希望哪位大侠指点一下。

view plain copy to clipboard print ?
  1. /**
  2. *MainActivity
  3. *
  4. *@authorzuolongsnail
  5. */
  6. publicclassMainActivityextendsActivity{
  7. privateEditTextnameET;
  8. privateEditTextnumberET;
  9. privateButtoninsertBtn;
  10. privateButtondeleteBtn;
  11. privateButtonqueryBtn;
  12. privateListViewcontentView;
  13. @Override
  14. publicvoidonCreate(BundlesavedInstanceState){
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.main);
  17. nameET=(EditText)findViewById(R.id.name);
  18. numberET=(EditText)findViewById(R.id.number);
  19. insertBtn=(Button)findViewById(R.id.insert);
  20. deleteBtn=(Button)findViewById(R.id.delete);
  21. queryBtn=(Button)findViewById(R.id.query);
  22. //用于显示数据
  23. contentView=(ListView)findViewById(R.id.content);
  24. insertBtn.setOnClickListener(newOperateOnClickListener());
  25. deleteBtn.setOnClickListener(newOperateOnClickListener());
  26. queryBtn.setOnClickListener(newOperateOnClickListener());
  27. }
  28. classOperateOnClickListenerimplementsOnClickListener{
  29. @Override
  30. publicvoidonClick(Viewv){
  31. Stringname=nameET.getText().toString();
  32. Stringnumber=numberET.getText().toString();
  33. Personp=newPerson(name,number);
  34. switch(v.getId()){
  35. //插入数据
  36. caseR.id.insert:
  37. insert(p);
  38. view();
  39. break;
  40. //删除数据
  41. caseR.id.delete:
  42. delete(name);
  43. view();
  44. break;
  45. //查询数据
  46. caseR.id.query:
  47. view();
  48. break;
  49. }
  50. }
  51. }
  52. //显示数据
  53. privatevoidview(){
  54. Cursorc=query("");
  55. ListAdapterlistAdapter=newSimpleCursorAdapter(this,R.layout.list,
  56. c,newString[]{People._ID,People.NAME,People.NUMBER},
  57. newint[]{R.id.id,R.id.name,R.id.number});
  58. contentView.setAdapter(listAdapter);
  59. }
  60. //插入联系人
  61. privatevoidinsert(Personp){
  62. //获得ContentResolver对象
  63. ContentResolvercr=getContentResolver();
  64. ContentValuesvalues=newContentValues();
  65. values.put(People.NAME,p.name);
  66. //表示是否把联系人添加到收藏(加星),1表示加入,0表示不加入,这行代码注释默认是不加入。
  67. values.put(Contacts.People.STARRED,1);
  68. Uriuri=Contacts.People.createPersonInMyContactsGroup(cr,values);
  69. //获得联系人People表的Uri
  70. Uriurl=Uri.withAppendedPath(uri,
  71. Contacts.People.Phones.CONTENT_DIRECTORY);
  72. values.clear();
  73. values.put(Contacts.Phones.TYPE,Contacts.Phones.NUMBER);
  74. values.put(Contacts.Phones.NUMBER,p.number);
  75. //插入操作
  76. cr.insert(url,values);
  77. }
  78. //插入联系人
  79. privatevoiddelete(Stringname){
  80. //获得ContentResolver对象
  81. ContentResolvercr=getContentResolver();
  82. Uriurl=Contacts.People.CONTENT_URI;
  83. //设置删除条件
  84. Stringwhere=People.NAME+"=?";
  85. String[]selectionArgs={name};
  86. cr.delete(url,where,selectionArgs);
  87. }
  88. //查询联系人
  89. privateCursorquery(Stringname){
  90. //获得ContentResolver对象
  91. ContentResolvercr=getContentResolver();
  92. Uriuri=Contacts.People.CONTENT_URI;
  93. //查询对象
  94. String[]projection={People._ID,People.NAME,People.NUMBER};
  95. //设置查询条件,这里我把selection和selectionArgs参数都设为null,表示查询全部数据
  96. Stringselection=null;
  97. String[]selectionArgs=null;
  98. if(!"".equals(name)){
  99. selection=People.NAME+"=?";
  100. selectionArgs=newString[]{name};
  101. }
  102. //设置排序条件
  103. StringsortOrder=Contacts.People._ID;
  104. Cursorc=cr.query(uri,projection,selection,selectionArgs,
  105. sortOrder);
  106. //if(c.moveToFirst()){
  107. //for(inti=0;i<c.getCount();i++){
  108. //c.moveToPosition(i);
  109. //Stringname=c.getString(c.getColumnIndexOrThrow(People.NAME));
  110. //Stringnumber=c.getString(c
  111. //.getColumnIndexOrThrow(People.NUMBER));
  112. //}
  113. //}
  114. returnc;
  115. }
  116. }

程序截图:

更多相关文章

  1. Android使用Realm数据库实现App中的收藏功能(代码详解)
  2. android之延时操作
  3. WIFI操作
  4. Android(安卓)文件路径详解
  5. Android树状列表实现
  6. Android数据通信——JSON&Gson(Android(安卓)studio)
  7. 1、传感器概述
  8. android基础部分再学习---android处理运行时配置发生变化
  9. 《Android第一行代码》first reading 二

随机推荐

  1. Android中调用天气预报
  2. [mark]Android(安卓)aapt工具
  3. Android: couldn't save which view has
  4. eclipse中使用RecyclerView报错:Error inf
  5. 与Android的系统打交道
  6. android下的android.os.StrictMode$Andro
  7. TextView字体逐渐变淡点以及程序特定list
  8. 解决Glide4.0和圆角裁剪CenterCrop冲突
  9. Ice Cream Sandwich系统将统一Android版
  10. Android(安卓)Build及相关类