Content Provider (컨텐드 제공자)
Posted on February 11th, 2009 by christopherJ
Content Provider
Sample Notepad 에서는 이 컨텐트제공자(Content Provider)의 개념을 많이 사용하고 있으므로 이를 이해하지 않고는 Tutorial을 뛰어넘는 난이도의 프로그램을 시작할 수 없습니다. 
컨텐트 제공자는 데이터를 모든 어플리케이션이 공유할수 있도록 하는 역할을 합니다. 이 방법을 이용하여 만들어진 데이터는 Public 하게 존재하며, 이것만이 모든 패키지들이 데이터를 공유할 수있는 단 하나의 방법입니다. 
컨텐트제공자내의 데이터는 SQLite 데이터베이스에서 읽어와 만들어질수도, 어플리케이션에 의해 그때 그때 입력될 수도 있습니다. 이러한 데이데의 입출력은 URI(유니크한 주소)를 중심으로 이루어집니다.
예)
content://media/internal/images 이 URI는 디바이스내의 모든 이미지 리스트를 보냅니다.
content://media/external/images 이 URI는 디바이스외부의 모든 이미지 리스트를 보냅니다.(예:SD 카드)
content://contacts/people/ 이 URI는 주소록의 모든 사람들 정보를 보냅니다content://contacts/people/23 이 URI는 주소록의 ID가 23 인 사람의 정보를 보냅니다
이 URI는 세부분으로 이루어지는데 다음 예에서 볼수있습니다
A: content://>로 Content URI 정의부
B 와 C: com.example.transportationprovider/train>데이터종류를 알려주는 부분.
D: 122>122이라는 특정 데이터를 지정하는 부분, 이부분이 없으면 train밑의 모든 데이터가 보내집니다.
아래에서는 데이터베이스 작업시의 중심인 4가지 명령을 기본으로 하나하나 컨텐트제공자가 사용되는지를 봅니다.
1. INSERT
이 작업에서는 ContentResolver.insert() 가 큰역할을 담당하게 됩니다. 예제를 봅니다.
ContentValues values = new ContentValues();
Uri phoneUri = null;
Uri emailUri = null;
values.put(Contacts.People.NAME, "New Contact");
//1 = the new contact is added to favorites
//0 = the new contact is not added to favorites
values.put(Contacts.People.STARRED,1);
//Add Phone Numbers
Uri uri = getContentResolver().insert(Contacts.People.CONTENT_URI, values);
//The best way to add Contacts data like Phone, email, IM is to
//get the CONTENT_URI of the contact just inserted from People's table,
//and use withAppendedPath to construct the new Uri to insert into.
phoneUri = Uri.withAppendedPath(uri, Contacts.People.Phones.CONTENT_DIRECTORY);
emailUri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
values.clear();
values.put(Contacts.Phones.TYPE, Phones.TYPE_MOBILE);
values.put(Contacts.Phones.NUMBER, "1233214567");
getContentResolver().insert(phoneUri, values);
values.clear();
values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
values.put(ContactMethods.DATA, "test@example.com");
values.put(ContactMethods.TYPE, ContactMethods.TYPE_HOME);
getContentResolver().insert(emailUri, values);
QUERY
아래는 가장 일반적인 조회의 예입니다.
string[] projection = new string[] {
People._ID,
People.NAME,
People.NUMBER, }; // 데이터를 뽑아낼 대상 칼럼들을 프로젝션에 정의합니다.
Uri mContacts = People.CONTENT_URI; 
Cursor managedCursor = managedQuery( mContacts,
projection, // 어느칼럼(Column)을 조회대상으로 할 것인가
null, // 선택할 줄(Row)을 지정하는 부분 (예, 2번째줄)
null, // 선택 조건
People.NAME + " ASC"); 정렬 조건
여기에서 manageQuery() 를 사용한다는 것과 마지막 부분에 그 결과값을 커서(Cursor)에 집어 넣는다는것을 염두에 두고 다음 예를 보면서 어떻게 값을 커서에서 빼는지 봅니다. 
private void getColumnData(Cursor cur){
if (cur.moveToFirst()) {
String name;
String phoneNumber;
int nameColumn = cur.getColumnIndex(People.NAME);
int phoneColumn = cur.getColumnIndex(People.NUMBER);
String imagePath; 
do {
name = cur.getString(nameColumn);
phoneNumber = cur.getString(phoneColumn);
// 이제 결과 값, name 과 phoneNumber로 무억이든할수있습니다.
} while (cur.moveToNext());
}

이제 커서로 보내진 조회결과에서 데이타를 하나하나 빼내는 작업이 수행됩니다. moveToFirst() 과 moveToNext()로 이리저리 움직이며 getColumnIndex() 로 원하는 컬럼의 인덱스 번호를 찾고 getString()으로 데이터를 뽑아냅니다.
Sample Notepad 와 Tutorial Notepadv3 를 비교 해보면 데이터베이스로 직접 저장하는것과 Content Provide에 저장하는 차이가 보입니다. 아래의 소스는 Sample Notepad에서 NoteEditor.java 내네 onPause() 부분에서 뽑은것으로 ContentValues 로 데이터가 보내짐이 보입니다. 
ContentValues values = new ContentValues();
values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
if (mState == STATE_INSERT) {
String title = text.substring(0, Math.min(30, length));
if (length>30) {
int lastSpace = title.lastIndexOf(' ');
if (lastSpace>0) {
title = title.substring(0, lastSpace);
}
}
values.put(Notes.TITLE, title);
}


복사했습니다!