본문으로 바로가기

Custom ContentPrivider 만들기 -1

category Android_app 2021. 2. 2. 13:58

1> Android Studio 실행
File --> New --> Other --> Content Provider 선택하기

 

 


URI Authorithies 값 추가후 Finish 눌러주세요.>> 추후 AndroidManifest.xml 의 provider tag 에서 수정해도 됩니다.

 

 


2개의 수정사항이 발생하네요. MyContentProvider.kt 생성 및 AndroidManifest.xml 에 provider tag 가 추가되었네요.

 

1> MyContentProvider.kt 소스코드

상속후 미수정 상태


override 함수  delete, getType, insert, onCreate, query, update  6개를 만들어 줘야 하네요.


2> AndroidManifest.xml 수정코드

 

<provider
android:name=".MyContentProvider"
android:authorities="com.leevisual.mykotlin.PROVIDER"
android:enabled="true"
android:exported="true"></provider>

 

>>  authorites 속성에   .PROVIDER 추가했습니다.

AndroidManifest.xml 규칙을 알고 싶은 분은 아래 사이트 방문해 주세요.

 

https://developer.android.com/guide/topics/manifest/provider-element?hl=ko

 

 |  Android 개발자  |  Android Developers

콘텐츠 제공자 구성요소를 선언합니다. 콘텐츠 제공자는 애플리케이션에서 관리되는 데이터에 구조적으로 액세스할 수 있게 하는 ContentProvider의 서브클래스입니다. 애플리케이션의 모든 콘텐

developer.android.com

에서 발췌 했습니다.

    <provider android:authorities="list"
              android:directBootAware=["true" | "false"]
              android:enabled=["true" | "false"]
              android:exported=["true" | "false"]
              android:grantUriPermissions=["true" | "false"]
              android:icon="drawable resource"
              android:initOrder="integer"
              android:label="string resource"
              android:multiprocess=["true" | "false"]
              android:name="string"
              android:permission="string"
              android:process="string"
              android:readPermission="string"
              android:syncable=["true" | "false"]
              android:writePermission="string" >
        . . .
    </provider>

 

MyContentProvider.kt 에 빌드에러가 많이 나오네요. (override 함수 작성 안했으니 당연하죠 )

  --> 이거 에러 수정할려니 SQLiteOpenHelper 상속한 클래스가 필요해 보이네요.


MyOwnDbHelper.kt 를 아래처럼 작성합니다.

영어 성적 표시를 위한 이름(name)과 점수(score) 항목만 추가했습니다.

아래 코드 이해 안가시면 제가 작성한 "SQLite을 이용한 custom database 사용하기" 참고하세요.

 

 

 

class MyOwnDbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME,null,DATABASE_VERSION) {

    private val TAG = MyOwnDbHelper::class.java.simpleName
    private val SQL_CREATE_ENTRIES =
            "CREATE TABLE ${MyContract.MyEntry.TABLE_NAME} (" +
                    "${BaseColumns._ID} INTEGER PRIMARY KEY," +
                    "${MyContract.MyEntry.COLUMN_NAME_TITLE} TEXT," +
                    "${MyContract.MyEntry.COLUMN_NAME_SCORE} INT)"
    private val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS ${MyContract.MyEntry.TABLE_NAME}"

    object MyContract {
        object MyEntry : BaseColumns {
            const val TABLE_NAME = "english"
            const val COLUMN_NAME_TITLE = "name"
            const val COLUMN_NAME_SCORE = "score"
        }
    }
    companion object{
        val DATABASE_NAME = "MyClassEnglishDb.db"
        val DATABASE_VERSION =1
    }

    override fun onCreate(p0: SQLiteDatabase?) {
        // CREATE TABLE tells the system to create a new database table keyword.
        Log.d(TAG,"onCreate() +")
        p0?.execSQL(SQL_CREATE_ENTRIES)
    }

    override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        Log.d(TAG,"onUpgrade() +")
        p0?.execSQL(SQL_DELETE_ENTRIES)
        onCreate(p0)
    }

}

 

 

 

 

 

위의 코드를 기반으로 다시 MyContentProvider.kt를 변경하겠습니다.

 

 

 

 

 

class MyContentProvider : ContentProvider() {
    val TAG = MyContentProvider::class.java.simpleName
    private lateinit var dbHelper : MyOwnDbHelper



    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        Log.d(TAG,"insert()")
        dbHelper.writableDatabase.insert(MyOwnDbHelper.MyContract.MyEntry.TABLE_NAME,null,values)
        context?.contentResolver?.notifyChange(uri, null)
        return uri
    }

    override fun onCreate(): Boolean {
        Log.d(TAG,"onCreate()")
        dbHelper = MyOwnDbHelper(context as Context)
        return true
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?,
                       selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
        Log.d(TAG,"query()")
        return dbHelper.readableDatabase.query(MyOwnDbHelper.MyContract.MyEntry.TABLE_NAME,projection,
                selection,selectionArgs,null,null,sortOrder)
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?,
                        selectionArgs: Array<String>?): Int {
        Log.d(TAG,"update()")
        val count =dbHelper.writableDatabase.update(MyOwnDbHelper.MyContract.MyEntry.TABLE_NAME,values, selection, selectionArgs)
        context?.contentResolver?.notifyChange(uri, null)
        return count
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        Log.d(TAG,"delete()")
        val count =dbHelper.writableDatabase.delete(MyOwnDbHelper.MyContract.MyEntry.TABLE_NAME,selection,selectionArgs)
        context?.contentResolver?.notifyChange(uri, null)
        return count
    }

    override fun getType(uri: Uri): String? {
        Log.d(TAG,"getType()")
        return null
    }

}

 

MainActivity에서 contentResolver를 사용해 query 호출하기

 

for_test1.setOnClickListener {
    val uri =Uri.parse("content://com.leevisual.mykotlin.PROVIDER")
    contentResolver.query(uri,null, null,null,null)
}

 

 

==> AndroidManifest.xml 의 android:authorities 값에 일치하면됩니다.

 

 

< 일단 여기까지 정리>

1> Empty Activity Project 생성  

2> ContentProvider 상속한 클래스 만들기 (MyContentProvider.kt)

  --> override 함수 추가 , 함수 내용은  미작성 상태로 남겨둡니다.

3> ContentProvider 에러 제거를 위한 MyOwnDbHelper 추가 ( SQLiteOpenHelper 상속)

4> MyContentProvider.kt 에 MyOwnDbHelper 기능 추가하기

5> MainActivity 에 contentResolver를 사용해 query 호출하기

 

반응형