728x90

연락처(Contacts)를 읽어오는 코드를 구현 테스트 중이다.

아래 코드를 테스트하면서 교보문고에 가서 책을 보니까 많은 시간이 걸리는 코드가 책에도 있더라.

읽어오는 연락처 데이터 개수가 적으면 아래 코드로도 빠른 응답 결과를 보여준다.

읽어올 데이터가 많다면 속도 문제 해결이 안되므로 해결을 위한 강구를 해야 한다.

해법은 데이터를 각각 읽어와서 메모리상에서 Join 하면 2천개 데이터를 가져오는데 1.5초 소요된다.


앱이 ContentProvider를 통해서 데이터에 접근할 때에는 ContentResolver를 통해서 접근하게 된다.
이 객체는 ContentProvider를 상속받아 특정 함수들을 보유하고 객체이다.
ContentResolver는 기존적인 CRUD(Create Retreive Update Delete) 함수들을 보유하고 있다.


Contacts 테이블에 있는 정보만 읽어오는 로직으로 구현시에는 2,000개의 데이터를 읽어오는 시간이 0.5초도 걸리지 않는다.

 public static Cursor LoadContactsCursor(ContentResolver contactHelper) {
    Uri contactUri = ContactsContract.Contacts.CONTENT_URI;
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " ASC";
    Cursor cursor = null;
    try {
        cursor = contactHelper.query(contactUri, null, null, null, sortOrder);
    } catch (Exception e){
        e.printStackTrace();
    }
    return cursor;
}

private ArrayList<String> contactRawContactID;
private ArrayList<String> contactNames;

contactRawContactID = new ArrayList<String>();
contactNames = new ArrayList<String>();

final SimpleDateFormat FORMATTER = new SimpleDateFormat("mm:ss:SSS");
long startTime = System.currentTimeMillis();
cursor = ContactHelper.LoadContactsCursor(getContentResolver());
System.out.println("연락처 개수 = " + cursor.getCount());
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
    contactRawContactID.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)));
    contactNames.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
    cursor.moveToNext();
}
cursor.close();
System.out.println("걸린시간 : " + FORMATTER.format(new Date(System.currentTimeMillis() - startTime)));



전화번호를 추가로 읽는 로직

 전화번호를 추가로 읽는 로직은 38초 소요된다.
 전화번호는 휴대폰번호, 사무실번호 2번 반복함에 따라 contactId 는 동일하지만 ArrayList 에 저장할 때 데이터가 따로 저장되므로 로직 구현을 고민해야 할 거 같다.

ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0) {
    int nCount=0; int mCount = 0;
    while (cur.moveToNext()) {
        nCount++;
        String contactId = 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) {
            Uri contactUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
            Cursor pCur = cr.query(contactUri, null, Phone.CONTACT_ID + " = ?", new String[]{contactId}, null);
            while (pCur.moveToNext()) {
                mCount++;
                int phoneType = pCur.getInt(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                switch (phoneType) {
                    case Phone.TYPE_MOBILE:
                        Log.e("nNo:"+nCount+" " + "mNo:"+mCount+" " +name + "(mobile number)", phoneNumber);
                        break;
                    case Phone.TYPE_HOME:
                        Log.e("nNo:"+nCount+" " + "mNo:"+mCount+" " +name + "(home number)", phoneNumber);
                        break;
                    case Phone.TYPE_WORK:
                        Log.e("nNo:"+nCount+" " + "mNo:"+mCount+" " +name + "(work number)", phoneNumber);
                        break;
                    case Phone.TYPE_OTHER:
                        Log.e("nNo:"+nCount+" " + "mNo:"+mCount+" " +name + "(other number)", phoneNumber);
                        break;
                    default:
                        break;
                }
            }
            pCur.close();
        }
    }
}



블로그 이미지

Link2Me

,