最近开发Android项目中遇到需要用到通讯录的需求,谷歌百度查了一下,根据自己的需求,利用ContentProvder的ContentResolver来获取的通讯录并封装的一个工具类ContactUtils
#####Demo效果图:
#####源码:
https://github.com/ok406lhq/ContactDemo
/**
* 获取通讯录工具类
* 返回的数据:
* [{
* "name": "xxx",
* "note": "呵呵呵呵",
* "phone": "13333333332"
* },
* {
* "name": "yyy",
* "phone": "13333333333"
* },
* {
* "name": "zzz",
* "phone": "13333333334"
* },
* ......
* ]
*/
public class ContactUtils {
public static ArrayList<MyContacts> getAllContacts(Context context) {
ArrayList<MyContacts> contacts = new ArrayList<MyContacts>();
Cursor cursor = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
//新建一个联系人实例
MyContacts temp = new MyContacts();
String contactId = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
//获取联系人姓名
String name = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
temp.name = name;
//获取联系人电话号码
Cursor phoneCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
while (phoneCursor.moveToNext()) {
String phone = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phone = phone.replace("-", "");
phone = phone.replace(" ", "");
temp.phone = phone;
}
//获取联系人备注信息
Cursor noteCursor = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
new String[]{ContactsContract.Data._ID, ContactsContract.CommonDataKinds.Nickname.NAME},
ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE + "'",
new String[]{contactId}, null);
if (noteCursor.moveToFirst()) {
do {
String note = noteCursor.getString(noteCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Nickname.NAME));
temp.note = note;
Log.i("note:", note);
} while (noteCursor.moveToNext());
}
contacts.add(temp);
//记得要把cursor给close掉
phoneCursor.close();
noteCursor.close();
}
cursor.close();
return contacts;
}
}
bean类MyContacts里包含了三个属性:name,phone,note(备注),这里就不贴代码了,都是可以根据IDE自动构建的getter、setter和toString。
需要注意的点有几个:
一、权限问题
在Android6.0版本加强了用户的安全体验,在2015年8月,Google发布了Android6.0版本,在用户权限的选择方面给了更灵活、更安全的操作方式。要知道原先(6.0之前)的用户对于权限的操作,只需要在安装时点击同意,所有权限就都给了,不然的话用户只能选择拒绝安装。也就是说,假如用户不想App获取通讯录等隐私信息,只能选择不安装应用。6.0开始,Google引入了权限申请机制,把权限分为危险权限和正常权限。
ok~科普结束。现在你要知道获取通讯录的权限是属于危险权限,需要动态申请该权限。
二、申请方法
在调用上述通讯录工具类之前,默认是没有权限的,需要动态申请权限:
(1)首先在AndroidManifest.xml中添加所需权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
(2)根据不同版本,封装一个方法来检查和申请权限
/**
* 动态权限
*/
public void addPermissByPermissionList(Activity activity, String[] permissions, int request) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //Android 6.0开始的动态权限,这里进行版本判断
ArrayList<String> mPermissionList = new ArrayList<>();
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(activity, permissions[i])
!= PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
if (mPermissionList.isEmpty()) { //非初次进入App且已授权
showContacts();
Toast.makeText(this, "已授权", Toast.LENGTH_SHORT).show();
} else {
//请求权限方法
String[] permissionsNew = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
ActivityCompat.requestPermissions(activity, permissionsNew, request); //这个触发下面onRequestPermissionsResult这个回调
}
}
}
(3)重写onRequestPermissionsResult方法根据用户的不同选择做出响应
/**
* requestPermissions的回调
* 一个或多个权限请求结果回调
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean hasAllGranted = true;
//判断是否拒绝 拒绝后要怎么处理 以及取消再次提示的处理
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
hasAllGranted = false;
break;
}
}
if (hasAllGranted) { //同意权限做的处理,开启服务提交通讯录
showContacts();
Toast.makeText(this, "同意授权", Toast.LENGTH_SHORT).show();
} else { //拒绝授权做的处理,弹出弹框提示用户授权
dealwithPermiss(MainActivity.this, permissions[0]);
}
}
引导处理权限拒绝之后的操作:
public void dealwithPermiss(final Activity context, String permission) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(context, permission)) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("操作提示")
.setMessage("注意:当前缺少必要权限!\n请点击“设置”-“权限”-打开所需权限\n最后点击两次后退按钮,即可返回")
.setPositiveButton("去授权", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", context.getApplicationContext().getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "取消操作", Toast.LENGTH_SHORT).show();
}
}).show();
}
}
Ps
当然你也可以使用RxPermission,这里有篇博客可以参考一下