안드로이드

ContentProvider & ContentResolver

코딩하는후운 2021. 8. 31. 16:02
반응형

안드로이드 4대 컴포넌트 중 ContentProvider에 대해 알아보려고 한다.

 

ContentProvider란?

안드로이드 응용 프로그램을 구성하는 컴포넌트 중 하나로서 데이터를 제공하는 역할을 하며 응용 프로그램끼리 데이터를 공유하는 유일한 방법이다.

A라는 앱과 B라는 앱 사이에 데이터를 공유한다고 생각하면 된다.

 

ContentProvider는 AndroidManifest에 등록 한다.

<provider

    android:name=".TestContentProvider" <!-- 클래스 맵핑 -->

    android:authorities="com.dabal.external" <!-- Uri Authority 정보 -->

    android:exported="true">  <!-- 외부 접근을 위한 옵션 -->

</provider>

 

여기서 포인트는 exported옵션이다.

ContentProvider가 개발중인 앱 내에서만 호출한다면 해당 옵션은 별도 처리 하지 않아도 되지만, 외부 앱에서 개발중인 앱을 호출하여 데이터를 제공해야 하는 경우, exported 옵션은 무조건 true로 주어야 한다.

 

  • exported 옵션을 true로 주어야 하는 이유?
    안드로이드 4.1이하 버전에서는 별도의 옵션 처리 없이도 ContentProvider는 항상 외부로 공개 되었으나, 4.2이상 버전에서는 보안성 개선을 위해 디폴트로 ContentProvider는 공개 되지 않으므로 개발자는 exported 옵션을 true로 지정하여 명시적으로 공개햐아 한다.

 

구현 방법

ContentProvider의 구현은 ContentProvider를 상속받아 구현

AndroidManifest에 작성한 클래스 맵핑의 클래스가 된다.

 

//외부 앱 연동용 ContentProvider

class TestContentProvider : ContentProvider() {

 

    

    //TestContentProvider 로드될 때 호출

    //제공할 데이터를 준비.

    override fun onCreate(): Boolean {

        return false

    }

 

    //외부에서 데이터 조회

    //보통 Uri, Projection(필드)로만 가져온다.

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

    return null

    }

 

    //제공하는 데이터의 MIME 타입을 조사하는 메서드.

    //정보의 개수에 따라 MIME 타입의 형식이 다름.

    //강제 규칙은 아니지만 대체로 다음 형식에 작성

    // 단수 : vnd.회사명.cursor.item/타입

    // 복수 : vnd.회사명.cursor.dir/타입

    override fun getType(uri: Uri?): String? {

        val uriMatcher = TestUriMatcher()

        return uri?.let {

            uriMatcher.getExternalCallInfo(uri)

        } ?: return null

    }

 

}

 

그 외 함수들

//외부에서 데이터 등록, 수정, 삭제는 제한한다.

insert(uri: Uri?, values: ContentValues?): Uri?

delete(uri: Uri?, selection: String?, selectionArgs: Array<String>?): Int

update(uri: Uri?, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int

//외부에서 메서드 호출 접근 시 처리한다.

call(method: String?, arg: String?, extras: Bundle?): Bundle

 

 

외부에서 연동하기

구현한 ContentProvider를 외부에서 호출하려면 ContentResolver를 통해 호출하면 된다.

 

private fun getData() {

    //ContentProvider 호출을 위한 Uri 생성

    val testUri: Uri = Uri.parse("content://authority/path/id")

 

    //ContentResolver 통한 데이터 반환

    val bundle: Bundle? = this.contentResolver.call(testURi, "getData()", null, null)

    val resultData: String? = bundle?.getString("result")

    resultString?.text = resultData

}

 

AndroidManifest에 등록한 ContentProvider 호출을 위한 Uri를 생성한다.

이때 Uri는 AndroidManifest에 등록한 Authority를 기반으로 생성한다.

 

생성된 uri를 바탕으로 contentResolver를 통해 메서드 콜하여 해당 데이터를 반환한다.

 

 

출처 : 

https://layers7.tistory.com/50

반응형