Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android_LoaderManager獲取聯系人

Android_LoaderManager獲取聯系人

編輯:關於Android編程

故事概況:小農在開發的時候隊長叫本人封裝一個工具類,直接調用就能調起系統通訊錄,選擇人員後,把電話號碼帶回到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 getContactPhone(Activity activityContext, Cursor cursor) {
        ArrayList arrayList = new ArrayList();
        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 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() {
                            @Override
                            public Loader onCreateLoader(int id, Bundle args) {
                                CursorLoader cursorLoader = new CursorLoader(activityContext);
                                cursorLoader.setUri(contactData);
                                return cursorLoader;
                            }

                            @Override
                            public void onLoadFinished(Loader loader, Cursor data) {
                                if (data != null && data.moveToFirst()) {
                                    String name = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                                    List 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 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;

/**
 * 
use like this
*
1, call gotoSystemContact
*
2, onActivityResult call getContactResult
* * 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 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 getContactPhone(Activity activityContext, Cursor cursor) { ArrayList arrayList = new ArrayList(); 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;

/**
 * 
use like this
*
1, call gotoSystemContact
*
2, onActivityResult call getContactResult
* * 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() { @Override public Loader onCreateLoader(int id, Bundle args) { CursorLoader cursorLoader = new CursorLoader(activityContext); cursorLoader.setUri(contactData); return cursorLoader; } @Override public void onLoadFinished(Loader loader, Cursor data) { if (data != null && data.moveToFirst()) { String name = data.getString(data.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); List 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 loader) { } } ); } } } /** * get contact phone * * @param cursor cursor * @return all phone nums */ public static List getContactPhone(Activity activityContext, Cursor cursor) { ArrayList arrayList = new ArrayList(); 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); } }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved