使用MediaStore Content Provider
Android MediaStore:是一个声音,视频,图片文件的托管地方。
无论什么时候你向文件系统增加了一个新的多媒体文件,你应该也需要使用Content Scanner将其加入到MediaStore。这样就能将多媒体资源暴露给其它APP,比如Media Player。
在大多数情况,你不需要直接去修改MediaStore里的内容。
如果获取MediaStore中的资源?
答:无论是外部还是内部:
MediaStore.<mediatype>.Media.EXTERNAL_CONTENT_URI 外部
MediaStore.<mediatype>.Media.INTERNAL_CONTENT_URI 内部
使用联系人Content Provider
Android提供给具有READ_CONTACTS权限的APP所有联系人的信息。
注意:Android 2.0(API 5)开始引入ContactsContract类,代替了要废除的Contacts类。
Contacts Contract使用3层数据模型去存储数据,下面介绍Contacts Contract的子类:
1.Data 表中的每行都定义了个人的数据集(电话号码,email地址,等等),用MIME类型区分开。尽管有为每个个人数据的类型预定义可用的列名(ContactsContract.CommonDataKinds里装有合适的MIME类型),此表能被用来存储任何值。
当向Data表中加入数据的时候,你需要指定与数据集相关的Raw Contact。
2.RawContacts 从Android 2.0(API 5)向前,用户可以增加多个联系人账户的Provider。RawContacts表中的每行定义了一个与数据集相关的账户。说白了就是账户信息。
3.Contacts Contacts表的行聚合了RawContacts中的数据,每行代表了不同的人信息。
Tip:
典型的,你会使用Data表去增删查改,相对于存在的联系人账户,RawContacts表用来创建和管理账户,Contact和Data表去查询数据库,从而获取联系人具体信息。
Contact表是通过Data表和RawContacts表聚合而成。Contact表中名字和ID是唯一的。Data表呢是没有名字信息的,但有其它的信息。(电话号码,等等)
当你要读取联系人数据的时候,你需要这个权限:
<uses-permission android:name=”android.permission.READ_CONTACTS”/>
下面这个例子,查询Contacts表,获取通讯录中的每个人的名字和ID:
// Create a projection that limits the result Cursor
// to the required columns.
String[] projection = {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME
};
// Get a Cursor over the Contacts Provider.
Cursor cursor =
getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
projection, null, null, null);
// Get the index of the columns.
int nameIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int idIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
// Initialize the result set.
String[] result = new String[cursor.getCount()];
// Iterate over the result Cursor.
while(cursor.moveToNext()) {
// Extract the name.
String name = cursor.getString(nameIdx);
// Extract the unique ID.
String id = cursor.getString(idIdx);
result[cursor.getPosition()] = name + “ (“ + id + “)”;
}
// Close the Cursor.
cursor.close();
我们通过前面的信息知道ContactsContract.Data表中存放着联系人的细节,比如地址,电话号码,email地址,照片等等。但是很多情况下,我们需要通过具体的联系人名字然后查到它的具体信息,怎么做呢?
答:为了简化这个查询,Android提供ContactsContract.Contacts.CONTENT_FILTER_URI。然后在这个URI上附加名字,然后查到相关的_id,然后通过这个id去Data中获取数据。
下面这个例子,就是使用类似的方式,获取指定联系人名字的电话号码和其他信息:
ContentResolver cr = getContentResolver();
String[] result = null;
// Find a contact using a partial name match
String searchName = “andy”;
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,
searchName);
// Create a projection of the required column names.
String[] projection = new String[] {
ContactsContract.Contacts._ID
};
// Get a Cursor that will return the ID(s) of the matched name.
Cursor idCursor = cr.query(lookupUri,
projection, null, null, null);
// Extract the first matching ID if it exists.
String id = null;
if (idCursor.moveToFirst()) {
int idIdx =
idCursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
id = idCursor.getString(idIdx);
}
// Close that Cursor.
idCursor.close();
// Create a new Cursor searching for the data associated with the returned Contact ID.
if (id != null) {
// Return all the PHONE data for the contact.
String where = ContactsContract.Data.CONTACT_ID +
“ = “ + id + “ AND “ +
ContactsContract.Data.MIMETYPE + “ = ‘” +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE +
“’”;
projection = new String[] {
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
Cursor dataCursor =
getContentResolver().query(ContactsContract.Data.CONTENT_URI,
projection, where, null, null);
// Get the indexes of the required columns.
int nameIdx =
dataCursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME);
int phoneIdx =
dataCursor.getColumnIndexOrThrow(
ContactsContract.CommonDataKinds.Phone.NUMBER);
result = new String[dataCursor.getCount()];
while(dataCursor.moveToNext()) {
// Extract the name.
String name = dataCursor.getString(nameIdx);
// Extract the phone number.
String number = dataCursor.getString(phoneIdx);
result[dataCursor.getPosition()] = name + “ (“ + number + “)”;
}
dataCursor.close();
}
还有一种情形,通过电话号码查询联系人信息:使用ContactsContract.PhoneLookup.CONTENT_FILTER_URI,附加上要查询的号码:
String incomingNumber = “(650)253-0000”;
String result = “Not Found”;
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
incomingNumber);
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME
};
Cursor cursor = getContentResolver().query(lookupUri,
projection, null, null, null);
if (cursor.moveToFirst()) {
int nameIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
result = cursor.getString(nameIdx);
}
cursor.close();
使用Intents获取联系人
此机制也就是使用Android原生联系人APP,查看,插入,或者选择一个联系人。
为了显示联系人信息:
使用Intent.ACTION_PICK,和ContactsContract.Contacts.CONTENT_URI.
private static int PICK_CONTACT = 0;
private void pickContact() {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
当然,既然进了别人的APP:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == PICK_CONTACT) && (resultCode == RESULT_OK)) {
resultTextView.setText(data.getData().toString());
}
}
插入:
使用ContactsContract.Intents.SHOW_OR_CREATE_CONTACT Action,将会查找指定的email地址或者电话号码URI,提供去插入一个新的条目(仅当你所指定的联系人的地址不存在的时候)。使用ContactsContract.Intents.Insert.xxx指定特定的值。
直接看例子:
Intent intent =
new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT,
ContactsContract.Contacts.CONTENT_URI);
intent.setData(Uri.parse(“tel:(650)253-0000”));
intent.putExtra(ContactsContract.Intents.Insert.COMPANY, “Google”);
intent.putExtra(ContactsContract.Intents.Insert.POSTAL,
“1600 Amphitheatre Parkway, Mountain View, California”);
startActivity(intent);
注意:前面说的这几个需要启动Activity,所以如果你自己写通讯录这个就不考虑了。