posted by By훈트 2010.07.27 22:09
일반적으로 어플리케이션에서 자료를 저장할 때 데이터베이스를 주로 사용합니다. 그런데, 한 어플리케이션 내에 저장되어 있는 데이터베이스에는 해당 어플리케이션 외에 다른 어플리케이션이 접근하는 것이 불가능합니다. 그렇다면, 다른 어플리케이션의 데이터에 접근할 수 있는 방법은 아예 없는 것일까요? 그렇지 않습니다. 만약 이렇게 데이터베이스 공유가 "완전히" 불가능할 경우 엄청난 재앙(?)이 발생합니다.

다른 어플리케이션에서 특정 어플리케이션의 데이터베이스에 직접 접근하는 것은 불가능합니다.


주소록 어플리케이션은 주소록 데이터를 데이터베이스에 저장하게 되는데, 이 주소록 데이터베이스에 주소록 어플리케이션만 접근 가능하고 다른 어플리케이션에서는 접근이 불가능하다면 주소록 정보를 이용하여 다른 서비스를 연동하는 것은 불가능하겠지요? 자칭 "경계가 없는 어플리케이션"을 추구하고 있는 안드로이드에서 기본적인 데이터 공유도 되지 않는다면 그건 말도 안되는 일이겠지요..

이 문제를 종합해보자면, 외부 어플리케이션이 마음대로 내 데이터베이스에 접근하지는 못하게 함과 동시에 내가 가진 데이터베이스 중 원하는 것들만 공유할 수 있도록 해주는 수단이 필요합니다. 안드로이드에서는 이런 역할을 컨텐트 프로바이더(Content Provider)라는 녀석이 해주게 됩니다.

컨텐트 프로바이더는 어플리케이션 내의 데이터베이스를 다른 어플리케이션이 사용할 수 있는 "통로"를 제공해줍니다. 이 과정에서 컨텐트 프로바이더를 통해 외부 어플리케이션이 접근할 수 있는 범위를 정해줄 수 있어, "공유할 것만 공유하는" 것이 가능합니다.

컨텐트 프로바이더와 컨텐트 리졸버

컨텐트 프로바이더를 사용하여 안드로이드 시스템의 각종 설정값이나 SD카드 내의 미디어 등에 접근하는 것이 가능합니다. 컨텐트 프로바이더에 접근하기 위해서는 해당 컨텐트 프로바이더의 주소가 필요합니다. 

컨텐트 프로바이더에 접근할 때는 컨텐트 프로바이더의 주소와 컨텐트 리졸버(Content Resolver)가 필요합니다. 컨텐트 리졸버는 컨텐트 프로바이더의 주소를 통해 해당 컨텐트 프로바이더에 접근하여 컨텐트 프로바이더의 데이터에 접근할 수 있도록 해주는 역할을 합니다.

컨텐트 리졸버는 액티비티 클래스 내의 getContentResolver()메소드를 통해 인스턴스를 받아올 수 있습니다. 일단 컨텐트 리졸버의 인스턴스를 받아온 후에는 query, insert 등의 메소드을 통해 데이터를 받거나 입력, 수정하고 싶은 컨텐트 프로바이더의 URI(Uniform Resource Identifier)를 넘겨주면 해당 컨텐트 프로바이더에 접근하여 요청한 작업을 수행할 수 있습니다. 

컨텐트 리졸버 및 컨텐트 프로바이더를 통한 데이터베이스 접근



컨텐트 프로바이더의 주소 구성

컨텐트 프로바이더의 주소는 컨텐트 프로바이더를 생성할 때 지정하며, URI(Uniform Resource Identifier) 형식으로 구성되어 있습니다. URI라는 단어 자체가 좀 생소할지도 모르겠습니다. 하지만 어렵게 생각할 것은 없습니다. URI는 우리가 인터넷 상의 자원의 주소를 표시할 때 쓰는 URL(Uniform Resource Identifier)의 상위 개념으로, 어떠한 자원의 위치를 표기하기 위한 형식입니다.

컨텐트 프로바이더의 주소(URI)는 일반적으로 아래와 같은 모습을 하고 있습니다.

content://AUTHORITY/PATH

인터넷 주소가 http:// 로 시작하는 것처럼, 컨텐트 프로바이더는 content://로 시작하는 주소를 가지고 있습니다. URI에서 http, content 등을 스키마(Scheme)라 합니다.

다음으로, AUTHORITY 부분입니다. AUTHORITY는 컨텐트 프로바이더의 고유 주소로, 뒤에 붙에 될 PATH와 함께 다른 어플리케이션에서 해당 컨텐트 프로바이더에 접근하기 위한 주소를 구성합니다. AUTHORITY는 다른 어플리케이션과 중복되면 안되므로, 일반적으로 자바 패키지 이름을  짓는 방식을 따라 이름을 지어줍니다. (예 : com.androidhuman.example) 인터넷 주소(URL)으로 치자면 사이트의 주소 (예:www.google.com) 부분이라 보시면 됩니다.

마지막으로 PATH(경로)는 즉 해당 프로바이더에서 제공하는 구체적인 데이터의 위치를 나타냅니다. 인터넷 주소로 치자면 세부 주소 (예: www.google.com/phone에서 phone 부분)라 할 수 있습니다.


컨텐트 프로바이더에서 제공하는 자료의 유형 구분

컨텐트 리졸버와 컨텐트 프로바이더의 주소를 통해 컨텐트 프로바이더에서 제공받는 데이터는 하나의 데이터일 수도 있고, 어떤 유형의 데이터 목록일 수도 있습니다. 이는 일반적으로 컨텐트 프로바이더의 주소를 통해 구분할 수 있지만, 좀 더 명확하게 해주기 위해 타입(MIME Type)을 지정해줍니다.

만약, 아래와 같은 컨텐트 프로바이더의 주소가 있다고 가정해봅시다.

contents://com.androidhuman.phoneprovider/phones

위의 컨텐트 프로바이더는 휴대폰 정보를 제공하는 컨텐트 프로바이더라 가정해보겠습니다. 위의 컨텐트 프로바이더의 AUTHORITY는 com.androidhuman.provider이고, Path는 phones 임을 알 수 있습니다. 위와 같은 형태의 주소는 일반적으로 어떤 항목에 해당하는 모든 데이터를 반환합니다. 위와 같은 경우는 모든 휴대폰 번호를 반환할 것이라 예측할 수 있죠.

Path는 컨텐트 프로바이더에 따라 여러 구조를 가질 수 있습니다. 아래와 같이 제조사별 휴대폰 목록을 제공하는 컨텐트 프로바이더가 있을 수도 있지요.

contents://com.androidhuman.phoneprovider/phones/lg
contents://com.androidhuman.phoneprovider/phones/samsung
contents://com.androidhuman.phoneprovider/phones/htc
contents://com.androidhuman.phoneprovider/phones/motorola

이런 식으로 "여러 개의 데이터"를 반환하는 컨텐트 프로바이더 주소(URI)는 타입으로 아래와 같은 형식을 갖습니다.

vnd.android.cursor.dir/vnd._CUSTOM_NAME_

위의 휴대폰 정보를 제공하는 컨텐트 프로바이더에서 휴대폰 목록을 제공하는 URI의 타임은 아래와 같이 지정할 수 있겠죠.

vnd.android.cursor.dir/vnd.androidhuman.phone

위와 같이 여러 개의 자료가 아닌, 딱 하나의 자료를 가리키는 컨텐트 프로바이더의 주소도 있습니다. 일반적으로 아래와 같은 형태를 하고 있지요.

contents://com.androidhuman.phoneprovider/phones/lg/1
contents://com.androidhuman.phoneprovider/phones/samsung/3

하나의 데이터를 가리키는 컨텐트 프로바이더의 URI는 위와 같이 뒤에 해당 데이터의 ID를 붙인 형태를 띕니다. 이러한 컨텐트 프로바이더 URI는 타입으로 아래와 같은 형태를 갖습니다.

vnd.android.cursor.item/vnd._CUSTOM_NAME

위의 컨텐트 프로바이더에서 휴대폰 하나를 가리키는 URI의 타입은 아래와 같이 표현할 수 있겠죠.

vnd.android.cursor.item/vnd.androidhuman.phone


컨텐트 프로바이더 URI 정리

컨텐트 프로바이더 URI에 대해 다시 한번 정리해보도록 합시다.



1. 컨텐트 프로바이더에 의해 제공되는 데이터임을 알립니다. 이 부분은 변하지 않습니다.
2. 컨텐트 프로바이더의 authority부분입니다. 각 컨텐트 프로바이더의 고유 이름입니다.
3. 컨텐트 프로바이더의 Path 부분이며, 어떤 데이터를 반환할지를 이 부분을 통해 지정합니다. 
4. 3번 부분의 Path 하위의 데이터 중 하나를 가리키는 것으로, 해당 데이터의 ID를 나타냅니다.


컨텐트 프로바이더는 일반적으로 아래와 같은 구조를 가집니다.

  • 어플리케이션의 컨텐트 프로바이더의 고유 주소 (AUTHORITY)
  • URI 필터링을 위한 UriMatcher객체 및 컨텐트 프로바이더가 처리할 수 있는 URI들
  • URI에 따른 Type을 반환하는 메소드
  • insert, update, delete, query 메소드
  • 어플리케이션 데이터베이스 정의부

[출처] http://androidhuman.tistory.com/279

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

티스토리 툴바