Android6.0的通讯录获取
来源:互联网 发布:软件质量管理指南 编辑:程序博客网 时间:2024/05/01 03:29
在Android Studio上实现基于Android6.0的通讯录获取功能
1、新建一个Android项目,API选择23: Android6.0(Marshmallow)
2、在MainActivity的layout中添加一个button用于获取通信录功能
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取联系人信息" android:id="@+id/btnGetContacts" android:layout_below="@+id/textView" android:layout_alignParentStart="true"/>
3、为了后续开发的方便和规整,新建一个包Contacts用于存放获取通讯录所需的类。并在包中新建一个Activity:GetContacts。
由于Android6.0对APP运行权限做了较大改变,获取通讯录信息不仅需要静态授权还需要动态申请权限,详情见
Android6.0系统权限那些事
http://www.open-open.com/lib/view/open1450578678148.html
Android 6.0 运行时权限处理完全解析
http://www.w2bc.com/article/101798?from=extend
所以在这里需要给APP添加动态申请权限代码,暂时先将其实现,下一篇博客再考虑封装。新建一个String类型的方法getContacts(Context context),第一步检查是否授权,如果没有授权就申请权限
if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.READ_CONTACTS) !=PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) context, new String[]{android.Manifest.permission.READ_CONTACTS}, 1); }
这里涉及到的API:
- ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。
- ActivityCompat.requestPermissions,该方法是异步的,第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以从方法名requestPermissions以及第二个参数看出,是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。
注:这里暂时没有考虑权限申请回调onRequestPermissionsResult()方法,只是为了跑通该程序,在下一篇博客再具体分析关于权限的事儿。
4、授权成功后,开始执行获取通讯录功能:
在写具体代码前,先新建一个类:ContactsInfo用于通讯录的数据封装。定义需要获取到的通讯录信息字符串,并写好构造函数。
public class ContactsInfo { private String name; private String number; private String sortKey; private int id; public ContactsInfo(String name,String number,String sortKey,int id){ setName(name); setNumber(number); setSortKey(sortKey); setId(id); }
定义一个ContactsInfo类型的List用于保存数据:public static List<ContactsInfo> list = new ArrayList<ContactsInfo>();
然后再开始写具体功能:
else { try { Uri contactUri =ContactsContract.CommonDataKinds.Phone.CONTENT_URI; Cursor cursor = context.getContentResolver().query(contactUri, new String[]{"display_name", "sort_key", "contact_id","data1"}, null, null, "sort_key"); String contactName; String contactNumber; String contactSortKey; int contactId; while (cursor.moveToNext()) { contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); contactSortKey =getSortkey(cursor.getString(1)); ContactsInfo contactsInfo = new ContactsInfo(contactName,contactNumber,contactSortKey,contactId); if (contactName!=null) list.add(contactsInfo); } cursor.close();//使用完后一定要将cursor关闭,不然会造成内存泄露等问题 }catch (Exception e){ e.printStackTrace(); }finally { context = null; }
这里使用了sort_key对获取到的通讯录信息进行了排序,实现一个方法:
private static String getSortkey(String sortKeyString){ String key =sortKeyString.substring(0,1).toUpperCase(); if (key.matches("[A-Z]")){ return key; }else return "#"; //获取sort key的首个字符,如果是英文字母就直接返回,否则返回#。 }
5、实现了基本功能后,我们需要将获取到的数据展示在界面上。
在GetContacts的layout中添加一张ListView
<ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ContactsLv" android:layout_weight="1"/>
之后需要自定义一个adapter用于对ListView的数据传递。新建一个类:ContactsAdapter 扩展自BaseAdapter,新建一个contacts布局来展示该adapter的界面,并重构其四个方法:
public class ContactsAdapter extends BaseAdapter{ private List<ContactsInfo> list; private Context context; public ContactsAdapter(List<ContactsInfo> list,Context context){ this.list = list; this.context = context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView == null){ convertView =LayoutInflater.from(context).inflate(R.layout.contacts,null); holder = new ViewHolder(); holder.nametv = (TextView) convertView.findViewById(R.id.contactName); holder.numbertv = (TextView) convertView.findViewById(R.id.contactNumber); holder.nametv.setText(list.get(position).getName()); holder.numbertv.setText(list.get(position).getNumber()); convertView.setTag(holder); }else { holder = (ViewHolder) convertView.getTag(); holder.nametv.setText(list.get(position).getName()); holder.numbertv.setText(list.get(position).getNumber()); } return convertView; } private static class ViewHolder{ TextView nametv; TextView numbertv; }}/** * ViewHolder就是一个持有者的类,他里面一般没有方法,只有属性,作用就是一个临时的储存器, * getView方法中每次返回的View存起来,可以下次再用。 * 这样做的好处就是不必每次都到布局文件中去拿到你的View,提高了效率。 */
这里使用了ViewHolder来对listvier进行优化
6、在GetContacts活动中将ListView与ContactsAdapter进行绑定:
private ListView ContactsLv; private ContactsAdapter adapter;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_get_contacts); GetContacts.getContacts(this); ContactsLv = (ListView) findViewById(R.id.ContactsLv); adapter = new ContactsAdapter(list, this); ContactsLv.setAdapter(adapter); }
另外,需要对list清除缓存,不然每一次运行都会重复加载数据:
@Override public void onBackPressed() { //清除缓存 list.clear(); super.onBackPressed(); }
7、OK,大功告成~~在MainActvity中增加对Button的监听即可。
- Android6.0的通讯录获取
- android6.0获取通讯录权限
- Android6.0通讯录权限问题
- Android6.0的通话记录获取
- 关于获取Android6.0的MAC地址
- Android6.0短信获取
- android6.0获取OTG
- Android6.0权限获取
- 通讯录的获取
- 通讯录的获取
- 通讯录的获取
- Android6.0动态获取权限
- android6.0动态获取权限
- android6.0获取wlan Mac
- android6.0动态获取权限
- Android6.0动态获取权限
- Android6.0 获取MAC地址
- Android6.0系统MAC地址获取的方法
- HDU3760 Ideal Path 逆bfs+贪心
- 分析进程、线程的终止
- spring mvc post请求参数所放的位置
- Virtualbox虚拟机中安装ubuntu
- Akka/play(activator) 2.5.3 创建工程 1
- Android6.0的通讯录获取
- python中schedule模块的使用
- 最优化与随机梯度下降
- Block的内存管理,看这里就够了
- 《C++精英内参之程序员高效指南》-12-8影响效率的不良习惯之科学的休息方法
- 超好用的C# json转换器。类js动态使用!
- templates
- BZOJ 4518: [Sdoi2016]征途
- 第四章 碰撞模块