안드로이드 앱을 구성하는 네 가지의 기본 요소는 Activity, Service, Broadcast Receiver, Content Provider 입니다. 그 중에서 Content Provider 는 어플리케이션 사이에서 Data 를 공유하는 통로 역할을 합니다. 컨텐트 프로바이더(Content Provider) 가 안드로이드 시스템의 각종 설정값이나 DB 에 접근하게 해 준다면 결과를 반환하는 브릿지 역할은 컨텐트 리졸버(Content Resolver) 가 하게 됩니다. 컨텐트 리졸버는 컨텐트 프로바이더의 주소를 통해 데이터에 접근해서 결과를 가져옵니다. 아래와 같은 구조가 되는 것이죠.
▼ 오늘은 ContentResolver 을 이용해서 ContentProvider 에 접근한 후 스마트폰에 있는 전화번호 정보를 가져와 보겠습니다. URI 주소만 안다면 어떤 정보라도 접근이 가능합니다. 먼저 ContentProvider 를 통해서 전화번호를 가져오기 위해서는 permission 을 얻어야 합니다. AndroidMenifest.xml 에 아래 permission 을 추가합니다.
<uses-permission android:name="android.permission.READ_CONTACTS"/>
데이터 접근을 위한 ContentResolver 는 getContentResolver() 메소드를 통해서 얻을 수 있습니다. ContentResovler 의 query() 함수를 이용해서 데이터를 조회하게 되는데 5개의 인수가 필요합니다.
ContentResolver : query(uri, projection, selection, selectionArgs, sortOrder) l uri : content://scheme 방식의 원하는 데이터를 가져오기 위한 정해진 주소 l projection : 가져올 컬럼 이름 목록, null이면 모든 컬럼 l selection : where 절에 해당하는 내용 l selectionArgs : selection에서 ?로 표시한 곳에 들어갈 데이터 l sortOrder : 정렬을 위한 order by 구문 |
▼ 아래 소스에서 query 함수의 첫 번째 인수인 전화번호를 가져오기 위한 URI 로 ContactsContract.Contacts.CONTENT_URI 가 입력되었습니다. 나머지 인수는 모두 null 이기 때문에 모든 전화번호를 가져오겠죠.
dataList = new ArrayList<Map<String, String>>();
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null, null, null,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " asc");
▼ 바로 전화번호 정보를 가져올 수 있는 것은 아닙니다. 위에서 조회한 정보를 바탕으로 다시 한번 더 query 함수로 데이터를 가져와야 합니다. 전화 번호 정보를 가져오기 위한 URI 는 ContactsContract.CommonDataKinds.Phone.CONTENT_URI 입니다. 데이터가 있다면 리턴 받은 Cursor 의 첫 번째 행에 전화번호가 들어 있습니다.
// ID로 전화 정보 조회
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
null, null);
// 데이터가 있는 경우
if (phoneCursor.moveToFirst()) {
String number = phoneCursor.getString(phoneCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
map.put("phone", number);
}
▼ 전체 소스는 다음과 같습니다. 조회한 전화번호와 이름을 ListView 위젯에 뿌리는 구조입니다. ListView 에 데이터를 채우기 위한 Adapter 는 SimpleAdapter 를 사용했습니다.
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ContentProviderActivity extends Activity implements View.OnClickListener{
private ArrayList<Map<String, String>> dataList;
private ListView mListview;
private Button mBtnAddress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_provider);
mListview = (ListView) findViewById(R.id.listview);
mBtnAddress = (Button) findViewById(R.id.btnAddress);
mBtnAddress.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAddress:
dataList = new ArrayList<Map<String, String>>();
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null, null, null,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " asc");
while (c.moveToNext()) {
HashMap<String, String> map = new HashMap<String, String>();
// 연락처 id 값
String id = c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
// 연락처 대표 이름
String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
map.put("name", name);
// ID로 전화 정보 조회
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
null, null);
// 데이터가 있는 경우
if (phoneCursor.moveToFirst()) {
String number = phoneCursor.getString(phoneCursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
map.put("phone", number);
}
phoneCursor.close();
dataList.add(map);
}// end while
c.close();
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(),
dataList,
android.R.layout.simple_list_item_2,
new String[]{"name", "phone"},
new int[]{android.R.id.text1, android.R.id.text2});
mListview.setAdapter(adapter);
}
}
}
▼ 메인 Activity 를 구성하는 레이아웃 xml 은 다음과 같습니다.
activity_content_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Address"
android:id="@+id/btnAddress"/>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/btnAddress"
android:id="@+id/listview" />
</RelativeLayout>
'안드로이드 개발' 카테고리의 다른 글
안드로이드 콘솔에서 adb shell 패키지 접근 권한 Permission denied 에러 해결 (1) | 2024.04.11 |
---|---|
안드로이드 개발 Intent 이용한 전화 걸기 (5) | 2024.03.23 |
안드로이드(Android) scale 이용해서 애니메이션(Animation) 구현하는 방법 (2) | 2024.03.07 |
안드로이드(Android) ProgressDialog(프로그레스 다이얼로그) 구현 방법 (9) | 2024.03.06 |
안드로이드 스튜디오 개발 APK 파일 찾는 방법 (0) | 2023.07.10 |
안드로이드(Android) ImageView scale type 별로 이미지 배치 하는 방법 (0) | 2023.01.24 |
안드로이드 개발 에러 have you declared this activity in your AndroidManifest.xml ? (0) | 2023.01.14 |
안드로이드 개발 에뮬레이터 카메라 QR 스캔하기 (1) | 2022.11.15 |