콘텐트 프로바이더 (ContentProvider)
콘텐트 프로바이더는 Android Application의 일부로써 앱간의 데이터를 공유할 수 있도 도와주는 컴포넌트이다.
콘텐트 프로바이더는 다음의 특징을 가진다.
- 콘텐트 프로바이더는 외부 앱에게 관계형 데이터베이스의 테이블과 유사한 하나 또는 그 이상의 테이블로써 제공한다.
- 하나의 행(Row)은 프로바이더가 제공하는 어떤 데이터 타입에 대한 객체를 나타내고, 그 행의 각 열(column)은 해당 객체가 가지고 있는 각 데이터를 나타낸다.
- 콘텐트 프로바이더(다른 앱)와 클라이언트(나의 앱)은 보안적으로 안전하게 연결되어 내부적으로 프로세스간 통신(IPC)을 한다.
콘텐트 프로바이더 동작 매커니즘
앱은 ContentProvider에 데이터를 접근하기 위해 앱의 Context에서 ContentResolver 객체를 사용한다.
- ContentResolver 객체는 ContentProvider를 구현(Implement)하는 클래스의 인스턴스와 통신할 수 있다. 해당 인스턴스는 클라이언트로 부터 데이터 요청을 수신하고 요청한 작업을 수행한 후 결과를 반환한다.
- ContentResolver 객체의 메소드를 통해 데이터를 생성, 검색 업데이트, 삭제 등을 할 수 있다. 마치 데이터 베이스에서 query를 하듯 ContentResolver의 query() 메소드가 컨텐트 프로바이더로부터 데이터와 관련된 작업을 하게 된다.
메커니즘
일반적으로 ContentProvider에 접근할 때 CusorLoader를 통해 백그라운드 에서 비동기 쿼리를 호출하고 ContentResolver를 사용하여 ContentProvider를 가져온다. 이렇게 하면 쿼리를 실행하는 동안 UI가 멈추지 않고 계속할 수 있다.
Content URI
Content URI는 프로바이더의 데이터를 가리키는 URI다.
Content URI는 프로바이더 자체(보통 패키지명)를 나타는 authority와 테이블을 가리키는 path를 포함한다.
- ContentResolver 객체는 그 URI의 authority부분을 시스템이 알고 있는 프로바이더들의 authority들과 비교하여 맞는 것을 찾아서 그 프로바이더로 query 인자들을 보낸다.
- ContentProvider는 액세스할 테이블을 알기 위해 URI의 apth부분을 확인한다. 프로바이더는 보통 그 path 부분과 일치하는 이름의 테이블을 가지고 있다.
content://com.example.provider/article/title 이런식으로 path/뒤에 구체적으로 어떠한 정보를 원하는지 명시하여 데이터를 받아올 수도 있다.
Content Provider로 부터 데이터 가져오기
예를 들어 사용자 사전 프로바이더에 있는 단어 및 장소 목록을 얻기 위해서 ContentResolver.query() 메소드를 호출하는데, 이것은 사용자 사전 프로바이더에 정의되어 있는 ContentProvider.query() 메소드를 호출한다.
1. 읽기 권한 요청
<uses-permission android:name="android.permission.READ_CONTACTS" />
2. 다른 앱의 ContentProvider에 쿼리 요청
ContentResolver resolver=getContentResolver();
Uri phoneUri= ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String proj[]={ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor= resolver.query(
phoneUri, //Uri: 프로바이더의 Table name과 대응(ex.. FROM table_name)
proj, //projection: select하여 가져올 데이터의 컬럼들과 대응
null, //selection: where 조건절(ex..WHERE col=value)
null, //selectionArgs
null); //sortOrder: 정렬기준(ex.. ORDER BY)
3. 결과 받아오기
위의 ContentResolver.query() 메소드는 쿼리의 Selection 조건에 부합하는 결과들에 대하여 쿼리의 projection에서 지정한 컬럼 값들을 담고 있는 Cursor 객체를 리턴해주며, Cursor객체를 통해 결과 값들에 엑세스 할 수 있다.
Cursor의 메소드들을 이용하여, 여러 행의 결과들에 대하여 순차적으로 각 행을 읽을 수 있고, 각 컬럼의 데이터 타입을 확인하여, 데이터를 얻을 수 있다.
..
..
//컨텐트 리졸버로 데이터 가져오기. 가져온형태 ->커서
Cursor cursor= resolver.query(phoneUri, proj,null,null,null);
//cursor에 데이터 존재여부
if(cursor !=null){
while(cursor.moveToNext()){
int index;
index=cursor.getColumnIndex(proj[1]);
String name=cursor.getString(index);
index=cursor.getColumnIndex(proj[2]);
String tel=cursor.getString(index);
}
}
cursor.close(); //닫지않으면 계속열려있음
데이터의 삽입, 갱신, 삭제
콘텐트 프로바이더로부터 데이터를 얻을 때와 마찬가지 방식으로 클라이언트(앱)이 다른앱의 데이터를 변경할 수도 있다.
ContentProvider에 대응되는 ContentResolver의 메소드를 호출하면 된다.
- ContentResolver.insert(..)
- ContentResolver.update(..)
- ContentResolver.delete(..)
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_1024.JPG");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
ContentResolver contentResolver = getContentResolver();
Uri item = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
insert() 함수는 Provider에 새로운 데이터를 추가하고 해당 데이터를 나타내는 URI를 리턴한다.
'Android > Android 기초' 카테고리의 다른 글
[Android] 프래그먼트(Fragment) (0) | 2023.09.06 |
---|---|
[Android] 인텐트(Intent)란 ? (0) | 2023.09.04 |
[Android] 안드로이드 4대 컴포넌트(3) - 브로드캐스트(BroadCast) (0) | 2023.09.03 |
[Android] 안드로이드 4대 컴포넌트(2) - 서비스(Service) (0) | 2023.09.03 |
[Android] 화면 회전시 액티비티(Activity)에서 데이터는 어떻게 저장해야할까? (0) | 2023.09.01 |