Android 開發 ContentProvider 獲取歌曲列表和聯系人的樣例
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 plaincopy to clipboardprint?
ContentResolver cr = 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
// 增加封裝音樂信息的代碼
// 查詢全部歌曲
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 musicDataMap = new HashMap();
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 plaincopy to clipboardprint?
public class MainActivity extends Activity {
private EditText nameET;
private EditText numberET;
private Button insertBtn;
private Button deleteBtn;
private Button queryBtn;
private ListView contentView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nameET = (EditText) findViewById(R.id.name);
numberET = (EditText) findViewById(R.id.number);
insertBtn = (Button) findViewById(R.id.insert);
deleteBtn = (Button) findViewById(R.id.delete);
queryBtn = (Button) findViewById(R.id.query);
// 用於顯示數據
contentView = (ListView) findViewById(R.id.content);
insertBtn.setOnClickListener(new OperateOnClickListener());
deleteBtn.setOnClickListener(new OperateOnClickListener());
queryBtn.setOnClickListener(new OperateOnClickListener());
}
class OperateOnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
String name = nameET.getText().toString();
String number = numberET.getText().toString();
Person p = new Person(name, number);
switch (v.getId()) {
// 插入數據
case R.id.insert:
insert(p);
view();
break;
// 刪除數據
case R.id.delete:
delete(name);
view();
break;
// 查詢數據
case R.id.query:
view();
break;
}
}
}
// 顯示數據
private void view() {
Cursor c = query("");
ListAdapter listAdapter = new SimpleCursorAdapter(this, R.layout.list,
c, new String[] { People._ID, People.NAME, People.NUMBER },
new int[] { R.id.id, R.id.name, R.id.number });
contentView.setAdapter(listAdapter);
}
// 插入聯系人
private void insert(Person p) {
// 獲得ContentResolver對象
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(People.NAME, p.name);
// 表示是否把聯系人增加到收藏(加星)。1表示增加,0表示不增加,這行代碼凝視默認是不增加。
values.put(Contacts.People.STARRED, 1);
Uri uri = Contacts.People.createPersonInMyContacts
// 獲得聯系人People表的Uri
Uri url = Uri.withAppendedPath(uri,
Contacts.People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(Contacts.Phones.TYPE, Contacts.Phones.NUMBER);
values.put(Contacts.Phones.NUMBER, p.number);
// 插入操作
cr.insert(url, values);
}
// 插入聯系人
private void delete(String name) {
// 獲得ContentResolver對象
ContentResolver cr = getContentResolver();
Uri url = Contacts.People.CONTENT_URI;
// 設置刪除條件
String where = People.NAME + "=?";
String[] selectionArgs = { name };
cr.delete(url, where, selectionArgs);
}
// 查詢聯系人
private Cursor query(String name) {
// 獲得ContentResolver對象
ContentResolver cr = getContentResolver();
Uri uri = Contacts.People.CONTENT_URI;
// 查詢對象
String[] projection = { People._ID, People.NAME, People.NUMBER };
// 設置查詢條件,這裏我把selection和selectionArgs參數都設為null。表示查詢所有數據
String selection = null;
String[] selectionArgs = null;
if (!"".equals(name)) {
selection = People.NAME + "=?";
selectionArgs = new String[] { name };
}
// 設置排序條件
String sortOrder = Contacts.People._ID;
Cursor c = cr.query(uri, projection, selection, selectionArgs,
sortOrder);
// if (c.moveToFirst()) {
// for (int i = 0; i < c.getCount(); i++) {
// c.moveToPosition(i);
// String name = c.getString(c.getColumnIndexOrThrow(People.NAME));
// String number = c.getString(c
// .getColumnIndexOrThrow(People.NUMBER));
// }
// }
return c;
}
}
Android 開發 ContentProvider 獲取歌曲列表和聯系人的樣例