Study/Android

콘텐츠 프로바이더

hegunhee 2022. 1. 4. 19:46

지난 글중에 액티비티 생명주기에대해 정리한것이 있지만 책을 보고 복습 겸 다시한번 정리하겠습니다.

위 글은 Do it! 깡쌤의 안드로이드 앱 프로그래밍 with 코틀린(강성윤 지음)을 보고 정리한 내용입니다.

 

콘텐츠 프로바이더는 앱끼리 데이터를 연동하는 컴포넌트 입니다. 앱을 개발하면서 다른 앱의 데이터를 사용할 때 콘텐츠 프로바이더를 이용합니다. 이때 데이터는 대상 앱의 데이터베이스나 파일 또는 앱에 할당된 메모리에 있습니다. 콘텐츠 프로바이더를 이용하면 이런 저장소에 있는 데이터를 가져오거나 수정할 수 있습니다.

 

어떤 앱의 데이터를 다른 앱에서 이용할 수 있게 하려면 콘텐츠 프로바이더를 이용해야 합니다.

내가 만든 앱의 데이터를 외부에 공개하려면 내 앱에 콘텐츠 프로바이더를 만들고 접근하는 방법을 제공해야 합니다. 그러면 외부 앱에서 콘텐츠 프로바이더를 이용해 공개한 데이터에 접근할 수 있습니다.

 

콘텐츠 프로바이더 작성하기


콘텐츠 프로바이더는 ContentProvider 클래스를 상속받아서 다음과 같이 작성합니다.

class MyContentProvider : ContentProvider() {

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        return 0
    }

    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

    override fun onCreate(): Boolean {
        return false
    }

    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? {
        return null
    }

    override fun update(
        uri: Uri, values: ContentValues?, selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        return 0
    }
}

ContentProvider를 상속받은 클래스에 onCreate(), getType(), query(), insert(), update(), dalete() 함수를 재정의해서 작성합니다. onCreate() 함수는 콘텐츠 프로바이더의 생명주기 함수이며 시스템이 콘텐츠 프로바이더 객체를 생성할 때 자동으로 호출합니다. 그리고 외부앱에서 query(), insert(), update(), delete() 함수 등을 호출해 데이터를 조작합니다.

 

만약 외부 요청으로 내부 함수들을 사용하는것을 허용하지 않겠다면 함수 내부를 구현하지 않으면 됩니다, 즉 외부에서 호출할 수 있도록 함수를 정의해 두되 아무 내용도 작성하지 않으면 됩니다.

 

콘텐츠 프로바이더도 안드로이드 컴포넌트이므로 매니페스트에 등록해야 합니다. 그런데 콘텐츠 프로바이더는 다른 컴포넌트와 달리 name 속성뿐만 아니라 authorities 속성도 반드시 선언해야 합니다.

<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.test_provider"
    android:enabled="true"
    android:exported="true"></provider>

콘텐츠 프로바이더는 <provider> 태그로 등록하며 name 속성은 등록하고자 하는 클래스명입니다. 그리고 authorities 속성은 외부에서 이 콘텐츠 프로바이더를 이용할 때 식별값으로 사용되는 문자열입니다. 따라서 authorities 속성값은 개발자가 지정하는 고유한 값이어야 합니다.

위 사진처럼 authorities값을 지정해줘야 합니다.

 

콘텐츠 프로바이더 이용하기


콘텐츠 프로바이더는 인텐트와 상관이 없습니다. 콘텐츠 프로바이더는 필요한 순간에 시스템에서 자동으로 생성해 주므로 query(), insert(), update(), delete() 함수만 호출해 주면 됩니다.

외부 앱에서 콘텐츠 프로바이더를 사용하려면 먼저 매니페스트에 해당 앱에 관한 패키지 공개 설정을 해줘야 합니다.

<queries>
	<package android:name="com.example.test_outer" />
</queries>

콘텐츠 프로바이더를 사용하는 앱의 매니페스트에 대상 앱의 패키지명을 <package> 태그로 명시합니다. 또는 사용하려는 콘텐츠 프로바이더의 authorities 속성을 <provider> 태그로 선언해 줘도 됩니다.

그리고 시스템에 등록된 콘텐츠 프로바이더를 사용할 때는 ContentResolver 객체를 이용합니다.

contentResolver.query(
	Uri.parse("content://com.example.test_provider"),
    null,null,null,null)

contentResolver 속성으로 ContentResolver객체를 얻은 후에 데이터를 조작하는 다음과 같은 함수를 호출하면 됩니다.

  • public final int delete(Uri, url, String where, String[] selectionArgs)
  • public final Uri insert(Uri, url, ContentValues values)
  • public final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  • public final int update(Uri uri,ContentValues values, String where,String[] selectionArgs)

이 함수들의 첫 번째 매개변수는 대상 콘텐츠 프로바이더를 식별하는 Uri 객체입니다. Uri 객체의 URL 문자열은 프로토콜명과 콘텐츠 프로바이더의 식별자로 등록된 authorities값이어야 합니다. 호스트에 지정한 문자열로 식별되는 콘텐츠 프로바이더의 query()나 insert(), update(),delete() 함수를 호출합니다.

Content://com.example.test_provider

-프로토콜-  --------호스트(host) <- authorities

콘텐츠 프로바이더를 이용할 때 URL 문자열에서 호스트 뒤에 다음처럼 경로를 설정할 수도 있습니다. 경로는 선택 사항이지만 이를 이용해 조건을 명시할 수 있습니다. 경로에는 단어나 숫자를 사용하는데 단어로 끝나면 그 단어에 해당하는 모든 데이터를 의미하고, 숫자로 끝나면 그 숫자로 식별되는 데이터를 의미하는 조건으로 주로 사용합니다.

Content://com.example.test_provider/user/1

-프로토콜-    ------호스트(host)--------------- 경로(path)

예를 들어 query() 함수를 호출하면서 첫 번째 매개변수인 Uri 객체의 문자열이 user로 끝난다면 user데이터를 모두 가져오겠다는 의미이며 user/1로 끝나면 user데이터에서 1번으로 식별되는 데이터를 가져오겠다는 의미입니다.

update(), insert() 함수의 매개변수로 지정되는 ContentValues는 Map 형태의 객체 집합입니다. 즉, 키-값으로 여러 건의 데이터를 ContentValues에 지정하고 이 객체를 insert(), update() 함수의 매개변수로 넘겨서 데이터를 저장하거나 수정합니다. 그리고 query() 함수의 반환타입인 Cursor도 가져올 데이터의 Map 객체입니다.

 

'Study > Android' 카테고리의 다른 글

Android의 Context  (0) 2022.04.04
안드로이드 데이터 바인딩  (0) 2022.01.17
바인딩 서비스  (0) 2021.12.29
서비스 컴포넌트  (0) 2021.12.24
액티비티 생명주기  (0) 2021.12.20