Android_LoaderManager获取联系人
来源:互联网 发布:传智播客java视频下载 编辑:程序博客网 时间:2024/06/05 01:02
故事概况:
小农在开发的时候队长叫本人封装一个工具类,直接调用就能调起系统通讯录,选择人员后,把电话号码带回到UI……..
于是故事开始了….
- 写一个静态的类用来调用方法
- 封装进入系统联系人界面的方法如下
// 进入系统通讯录界面 public static void gotoSystemContact(Activity activityContext, int requestCode) { Intent moblieIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); activityContext.startActivityForResult(moblieIntent, requestCode); }
- 写一个获取联系人内容的方法,
/** * get contact phone * * @param cursor cursor * @return all phone nums */ private static List<String> getContactPhone(Activity activityContext, Cursor cursor) { ArrayList<String> arrayList = new ArrayList<String>(); Cursor phone = null; try { int phoneColumn = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); int phoneNum = cursor.getInt(phoneColumn); if (phoneNum > 0) { int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); String contactId = cursor.getString(idColumn); phone = activityContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null); if (phone != null && phone.moveToFirst()) { for (; !phone.isAfterLast(); phone.moveToNext()) { int index = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); int typeindex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); int phone_type = phone.getInt(typeindex); String phoneNumber = phone.getString(index).trim(); arrayList.add(phoneNumber); } } } } catch (Exception e) { } if (phone != null && !phone.isClosed()) { phone.close(); } return arrayList; }
- 解析联系人去除空格乱七八糟的如下方法
/** * onActivityResult call the method get the contact phone num * * @param activityContext activity * @param data onActivityresult data * @return phoneNum */ public static String getContactResult(Activity activityContext, Intent data) { String phoneNum = ""; Cursor cursor = null; try { if (data != null) { Uri contactData = data.getData(); if (contactData != null) { cursor = activityContext.managedQuery(contactData, null, null, null, null); } if (cursor != null && cursor.moveToFirst()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); List<String> numbers = getContactPhone(activityContext, cursor); if (numbers != null && numbers.size() > 0) { String[] mPhoneNumbers = new String[numbers.size()]; for (int i = 0; i < numbers.size(); i++) { String number = numbers.get(i); String newNumber = number.replaceAll("[^\\d]", ""); mPhoneNumbers[i] = newNumber; } phoneNum = mPhoneNumbers[0]; } } } } catch (Exception e) { } return phoneNum; }
就是这个方法,看到没有很顺利的返回了 phoneNum,但是数据库的coucor没有关闭,一个严谨的程序员怎么能忍受游标不关闭呢,其实我是能忍受的…..队长不能接受,必须要关闭 关闭能带来的问题是什么,第一次能获取到联系人号码,然后第二次执行的时候 在UI的onActivityResult里面会崩溃并且报游标关闭错误….
如下图:
但是如果你不关闭游标的话…..传说中的代码不严谨,内存泄漏什么的一堆,于是就的改…牺牲点app内存和一点点的代码不严谨你完成这个功能就需要一个操作,
ctr + D 删除关闭代码就行了…
但是这不允许,第一用了过时的API,第二游标必须关闭,所以只能修改实现方式
- 新的实现方法,采用LoaderManager来完成,
我们修改下获取手机号的方法如下
/** * onActivityResult call the method get the contact phone num * * @param activityContext activity * @param data data * @param phoneNumGetListener phone num callback */ public static void getContactResult(final Activity activityContext, Intent data, final OnPhoneNumGetListener phoneNumGetListener) { if (data != null) { final Uri contactData = data.getData(); if (contactData != null) { activityContext.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { CursorLoader cursorLoader = new CursorLoader(activityContext); cursorLoader.setUri(contactData); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (data != null && data.moveToFirst()) { String name = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); List<String> numbers = getContactPhone(activityContext, data); if (numbers != null && numbers.size() > 0) { String[] mPhoneNumbers = new String[numbers.size()]; for (int i = 0; i < numbers.size(); i++) { String number = numbers.get(i); String newNumber = number.replaceAll("[^\\d]", ""); mPhoneNumbers[i] = newNumber; } if (phoneNumGetListener != null) { phoneNumGetListener.getPhoneNum(mPhoneNumbers[0]); } } data.close(); // when get data do not forget destoryloader activityContext.getLoaderManager().destroyLoader(0); } } @Override public void onLoaderReset(Loader<Cursor> loader) { } } ); } } }
这里我们传入了获得到手机号的一个异步回调,这就是LoaderManager的最大的区别,cursor = activityContext.managedQuery(contactData, null, null, null, null);
这方法是同步的,而且这个方法是过时的……
这样我们获取手机号的方法和解析就放到了 onLoadFinished里面
代码基本就这么多,activity里面只需要这样既可
@Override protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == MOBILE_REQUEST_CODE) { ATContactUtilLoadManager.getContactResult(this, data, new ATContactUtilLoadManager.OnPhoneNumGetListener() { @Override public void getPhoneNum(String num) { phoneNum.setText("loadmanager得到的>>>> " + num); } }); } }
这样我们就能通过loadmanager拿到手机号了,关键的是curcor关闭了,任务完成了…..可能是最近看乔布斯传魔怔了,要是以前的脾气,早就pk起来了 ,删除一句代码就能解决干嘛费劲搞这个loadermanager
反过来想想加入 谷歌删除了过时的API. 或者由于你这个游标没关闭造成的内存泄漏正好达到crash的内存上限..罪过就大了..从自我做起吧,写一篇博客记录下今天的内容,两种工具类喜欢的可以看下
完整代码如下:
**
- 第一种普通方法代码
**
package com.asiatravel.atjardemo.utils;import android.app.Activity;import android.content.Intent;import android.database.Cursor;import android.net.Uri;import android.provider.ContactsContract;import java.util.ArrayList;import java.util.List;/** * <pre>use like this</pre> * <pre>1, call gotoSystemContact</pre> * <pre>2, onActivityResult call getContactResult</pre> * * Created by jsion on 16/5/10. */public class ATContactUtilNormal { private ATContactUtilNormal() { } public static void gotoSystemContact(Activity activityContext, int requestCode) { Intent moblieIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); activityContext.startActivityForResult(moblieIntent, requestCode); } /** * onActivityResult call the method get the contact phone num * * @param activityContext activity * @param data onActivityresult data * @return phoneNum */ public static String getContactResult(Activity activityContext, Intent data) { String phoneNum = ""; Cursor cursor = null; try { if (data != null) { Uri contactData = data.getData(); if (contactData != null) { cursor = activityContext.managedQuery(contactData, null, null, null, null); } if (cursor != null && cursor.moveToFirst()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); List<String> numbers = getContactPhone(activityContext, cursor); if (numbers != null && numbers.size() > 0) { String[] mPhoneNumbers = new String[numbers.size()]; for (int i = 0; i < numbers.size(); i++) { String number = numbers.get(i); String newNumber = number.replaceAll("[^\\d]", ""); mPhoneNumbers[i] = newNumber; } phoneNum = mPhoneNumbers[0]; } } } } catch (Exception e) { } return phoneNum; } /** * get contact phone * * @param cursor cursor * @return all phone nums */ private static List<String> getContactPhone(Activity activityContext, Cursor cursor) { ArrayList<String> arrayList = new ArrayList<String>(); Cursor phone = null; try { int phoneColumn = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); int phoneNum = cursor.getInt(phoneColumn); if (phoneNum > 0) { int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); String contactId = cursor.getString(idColumn); phone = activityContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null); if (phone != null && phone.moveToFirst()) { for (; !phone.isAfterLast(); phone.moveToNext()) { int index = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); int typeindex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); int phone_type = phone.getInt(typeindex); String phoneNumber = phone.getString(index).trim(); arrayList.add(phoneNumber); } } } } catch (Exception e) { } if (phone != null && !phone.isClosed()) { phone.close(); } return arrayList; }}
**
- 第二种,loadermanager实现
**
package com.asiatravel.atjardemo.utils;import android.app.Activity;import android.app.LoaderManager;import android.content.CursorLoader;import android.content.Intent;import android.content.Loader;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract;import java.util.ArrayList;import java.util.List;/** * <pre>use like this</pre> * <pre>1, call gotoSystemContact</pre> * <pre>2, onActivityResult call getContactResult</pre> * * Created by jsion on 16/5/10. */public class ATContactUtilLoadManager { private ATContactUtilLoadManager() { } public static void gotoSystemContact(Activity activityContext, int requestCode) { Intent moblieIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); activityContext.startActivityForResult(moblieIntent, requestCode); } /** * onActivityResult call the method get the contact phone num * * @param activityContext activity * @param data onActivityresult data * @return phoneNum */ public static void getContactResult(final Activity activityContext, Intent data, final OnPhoneNumGetListener phoneNumGetListener) { if (data != null) { final Uri contactData = data.getData(); if (contactData != null) { activityContext.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { CursorLoader cursorLoader = new CursorLoader(activityContext); cursorLoader.setUri(contactData); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (data != null && data.moveToFirst()) { String name = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); List<String> numbers = ATContactUtilLoadManager.getContactPhone(activityContext, data); if (numbers != null && numbers.size() > 0) { String[] mPhoneNumbers = new String[numbers.size()]; for (int i = 0; i < numbers.size(); i++) { String number = numbers.get(i); String newNumber = number.replaceAll("[^\\d]", ""); mPhoneNumbers[i] = newNumber; } if (phoneNumGetListener != null) { phoneNumGetListener.getPhoneNum(mPhoneNumbers[0]); } } data.close(); activityContext.getLoaderManager().destroyLoader(0); } } @Override public void onLoaderReset(Loader<Cursor> loader) { } } ); } } } /** * get contact phone * * @param cursor cursor * @return all phone nums */ public static List<String> getContactPhone(Activity activityContext, Cursor cursor) { ArrayList<String> arrayList = new ArrayList<String>(); Cursor phone = null; try { int phoneColumn = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); int phoneNum = cursor.getInt(phoneColumn); if (phoneNum > 0) { int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); String contactId = cursor.getString(idColumn); phone = activityContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null); if (phone != null && phone.moveToFirst()) { for (; !phone.isAfterLast(); phone.moveToNext()) { int index = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); int typeindex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); int phone_type = phone.getInt(typeindex); String phoneNumber = phone.getString(index).trim(); arrayList.add(phoneNumber); } } } } catch (Exception e) {// ATLogUtil.e(e.toString()); } if (phone != null && !phone.isClosed()) { phone.close(); } return arrayList; } public interface OnPhoneNumGetListener { void getPhoneNum(String phoneNum); }}
- Android_LoaderManager获取联系人
- 获取联系人
- 获取联系人
- 获取联系人
- 获取联系人
- 通讯录, 获取联系人, 删除联系人
- android2.1获取联系人
- 获取android联系人信息
- 获取联系人头像
- android获取联系人信息
- 获取联系人所有信息
- android 获取联系人
- 获取联系人头像
- Android获取联系人列表
- android获取联系人信息
- 获取android联系人信息
- Java获取邮箱联系人
- Android 获取联系人资料。
- 【DirectX11】第五篇 Hello,Shaders!
- 不错的第三方
- java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.m
- 关于TortoiseSVN的全局忽略列表
- https原理及tomcat配置https方法
- Android_LoaderManager获取联系人
- 怎样写一个增广矩阵到txt文件中
- wowza 配置自己的VOD-Edge 实现一个vod点播
- CSS
- 基于springjdbc封装的javaee轻量级开发平台jmapper(一)
- C++作业5
- Android WebView 不支持 H5 input type="file" 解决方法
- ubuntu下的hadoop安装
- session 和 cookie