2012-06-06 2 views
5

Android 장치의 연락처를 가져 오려고합니다. 나는 좋은 샘플 코드연락처 가져 오기 성능 문제가 발생했습니다.

here을 발견하지만, ListActivity은 시간이 많이 걸리는 그 코드를 사용하는 ArrayAdapter 채워하려고 할 때 - 거의 4 갤럭시 S2에 초 이상 장치에 더 많은. 그 성능을 향상시켜야합니다. 내가 생각하기에 Cursor을 구현하고 하나 이상의 차원을 보유하고 Cursor, SimpleCursorAdapter을 목록 어댑터로 사용합니다.
나는이 방법으로 몇 가지 문제를 참조하십시오

  • 내가 특정 위치에 항목을 얻을하는 방법을 모르겠어요.
  • 각 커서마다 다른 열이 있습니다.

더 좋고/더 쉬운 방법이 있습니까?

편집 : 사용 a

public List<ContactData> readContacts(){ 
    ContentResolver cr = getContentResolver(); 
    List<ContactData> cd = new ArrayList<ContactData>(); 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
         new String[]{ContactsContract.CommonDataKinds.Phone._ID,ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY}, 
         ContactsContract.CommonDataKinds.Phone.NUMBER + " IS NOT NULL", 
             null, 
             ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY); 
       while (pCur.moveToNext()) { 
        String phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        String id = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID)); 
        String name = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY)); 
         ContactData cd1 = contactDataProvider.get(); 
         cd1.id = id; 
         cd1.name = name; 
         cd1.phone = phone; 
         cd.add(cd1); 
       } 
       pCur.close(); 
    return cd; 
} 
+0

각 ListFragment 행에서 렌더링하려는 연락처의 데이터 조각의 완전하고 정확한 목록은 무엇입니까? – CommonsWare

+0

코드 샘플을 추가했습니다. (ID, 이름, 전화 번호) – oshai

답변

4

당신은 당신이 전화 번호를 동시에 이름과 ID를 얻을 수 있습니다 :

String[] PROJECTION=new String[] {Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER}; 
Cursor pCur = cr.query(Phone.CONTENT_URI, PROJECTION, Phone.CONTACT_ID +" = ?", 
             new String[]{id}, null); 

이 당 행 서브 쿼리를 제거합니다.

+0

작동합니다. 감사합니다! 나는 그것을 사용했지만 또한 모든 사용자의 모든 전화를 얻으려면 ID로 필터링을 제거했습니다. – oshai

3

:

하나 개의 쿼리로 변경하여 그것을 해결하기 위해 관리 : 2

public List<ContactData> readContacts(){ 
    ContentResolver cr = getContentResolver(); 
    List<ContactData> cd = new ArrayList<ContactData>(); 
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, 
      null, null, null, ContactsContract.Contacts.DISPLAY_NAME); 

    if (cur.getCount() > 0) { 
     while (cur.moveToNext()) { 
      String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
      String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
      if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { 

       // get the phone number 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
             ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", 
             new String[]{id}, null); 
       while (pCur.moveToNext()) { 
        String phone = pCur.getString(
          pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        if (!Utils.isEmpty(phone)) { 
         cd.add(new ContactData(id, name, phone)); 
        } 
       } 
       pCur.close(); 


      } 
     } 
    } 
    return cd; 
} 

편집 : 여기

내 코드입니다 Cursor은이 문제에 대한 훌륭한 접근 방법입니다. 특정 위치에서 정보를 검색하려면 Cursor.moveToPosition(int position)을 사용할 수 있습니다. 그런 다음 Cursor,이 경우 String의 모든 입력란에 Cursor.getString(int columnIndex)을 사용하여 액세스 할 수 있습니다.

자세한 내용은 Cursor 설명서를 참조하십시오.

가장 좋은 방법은 CursorLoader을 구현하여 백그라운드 데이터 검색을 수행하는 것입니다. 또한 자동으로 데이터 변경, 방향 변경 등에 대한 ListView의 재 처리를 처리합니다. 자세한 설명은 this great tutorial을 확인하십시오.

+1

CursorLoader는 좋은 방법입니다. 또한 서로 내부에서 쿼리를 중첩하는 데주의해야합니다. 마지막으로, 필요한 정보 만 선택해야합니다. –

관련 문제