본문 바로가기
안드로이드/데이터 입출력

안드로이드 Content Provider

by 김어찐 2022. 6. 23.
728x90

안드로이드 4대 구성 요소 중 하나로 애플리케이션이 저장한 데이터를 다른 애플리케이션이 사용할 수 있도록 제공하는 개념이다.

 

 

안드로이드 11버전부터 변경된 점

안드로이드 11 부터 다른 애플리케이션의 요소를 사용할 때는 AndroidManifest.xml에 명시해야 한다.

 

https://developer.android.com/training/basics/intents/package-visibility?hl=ko 

 

패키지 공개 상태 관리  |  Android 개발자  |  Android Developers

패키지 공개 상태 관리 앱을 만들 때는 기기에 설치된 다른 앱, 즉 내 앱에서 액세스하려는 앱을 표시하는 패키지 집합을 고려하는 것이 중요합니다. 앱이 Android 11(API 수준 30) 이상을 타겟팅한다

developer.android.com

 

 

App1

package com.example.contentprovider

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button.setOnClickListener {
            val helper = DBHelper(this)

            val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            val now = sdf.format(Date())

            val sql = """
                insert into TestTable
                (textData, intData, floatData, dateData)
                values (?,?,?,?)
            """.trimIndent()

            val arg1 = arrayOf("문자열1","100","11.11",now)
            val arg2 = arrayOf("문자열2","200","22.22",now)

            helper.writableDatabase.execSQL(sql,arg1)
            helper.writableDatabase.execSQL(sql,arg2)

            helper.writableDatabase.close()

            textView.text = "저장완료"


        }

        button2.setOnClickListener {
            val helper = DBHelper(this)

            val sql = "select * from TestTable"

            val c1 = helper.writableDatabase.rawQuery(sql,null)

            textView.text = ""
            while (c1.moveToNext()) {
                val idx1 = c1.getColumnIndex("idx")
                val idx2 = c1.getColumnIndex("textData")
                val idx3 = c1.getColumnIndex("intData")
                val idx4 = c1.getColumnIndex("floatData")
                val idx5 = c1.getColumnIndex("dateData")

                val idx = c1.getInt(idx1)
                val textData = c1.getString(idx2)
                val intData = c1.getInt(idx3)
                val floatData = c1.getDouble(idx4)
                val dateData = c1.getString(idx5)

                textView.append("idx : $idx\n")
                textView.append("textData : $textData\n")
                textView.append("intData : $intData\n")
                textView.append("floatData : $floatData\n")
                textView.append("dateData : $dateData\n")
            }

            helper.writableDatabase.close()
        }
    }
}

 

package com.example.contentprovider

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class DBHelper : SQLiteOpenHelper {

    constructor(context: Context) : super(context,"Test.db",null,1)

    override fun onCreate(db: SQLiteDatabase?) {
        val sql = """
            create table TestTable
            (idx integer primary key autoincrement,
            textData text not null,
            intData integer not null,
            floatData real not null,
            dateData date not null)
        """.trimIndent()

        db?.execSQL(sql)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        TODO("Not yet implemented")
    }
}

 

Content Provider 생성

package com.example.contentprovider

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.net.Uri

class TestProvider : ContentProvider() {

    var db:SQLiteDatabase? = null

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        val cnt = db?.delete("TestTable",selection,selectionArgs)
        return cnt!!
    }

    // 열의 데이터 타임을 MIME 타입 형태로 반환하는 메서드
    // 알려줄 필요가 없다면 null을 반환한다.
    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        db?.insert("TestTable",null,values)

        return uri
    }

    // 컨텐트 프로비아더 객체가 생성되면 자동으로 호출되는 메서드
    // 데이터베이스에 접근할 수 있는 객체를 생서하고
    // 접속에 성공하는 true, 실패하면 false를 반환해준다.
    override fun onCreate(): Boolean {
        db = DBHelper(context!!).writableDatabase

        if (db == null) {
            return false
        }
        return true
    }

    // select 용
    // uri : 프로바이더 요청시 사용한 uri 값
    // projection : 가여올 컬럼 이름 목록, null이면 모든 컬럼을 가져온다.
    // selection : 조건절, null이면 조건이 없다
    // selectionArgs : 조건절 "?"에 바인딩 될 값 배열
    // sortOrder : 정렬 기준이되는 컬럼
    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? {
        val c1 = db?.query("TestTable",projection,selection,selectionArgs,null,null,sortOrder)
        return c1
    }

    override fun update(
        uri: Uri, values: ContentValues?, selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        val cnt = db?.update("TestTable",values,selection,selectionArgs)
        return cnt!!
    }
}

 

 

App 2

package com.example.cpapp2

import android.content.ContentValues
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button.setOnClickListener {
            // Content Provider의 이름을 가지고 있는 uri 객체를 생성한다.
            val uri = Uri.parse("content://kr.co.softcampus.dbprovider")

            // 첫 번쨰 : 접속할 프로바이더 uri
            // 두 번째 : 가져올 컬럼 목록 배열, null이면 모두 가져온다
            // 세 번째 : 조건절
            // 네 번째 : 조건절 "?"에 바인딩 될 값 배열
            // 다섯 번째 : 정렬 기준
           val c1 = contentResolver.query(uri,null,null,null,null)

            textView.text = ""
            while (c1?.moveToNext()!!) {
                val idx1 = c1?.getColumnIndex("idx")
                val idx2 = c1?.getColumnIndex("textData")
                val idx3 = c1?.getColumnIndex("intData")
                val idx4 = c1?.getColumnIndex("floatData")
                val idx5 = c1?.getColumnIndex("dateData")

                val idx = c1?.getInt(idx1)
                val textData = c1?.getString(idx2)
                val intData = c1?.getInt(idx3)
                val floatData = c1?.getDouble(idx4)
                val dateData = c1?.getString(idx5)

                textView.append("idx : $idx\n")
                textView.append("textData : $textData\n")
                textView.append("intData : $intData\n")
                textView.append("floatData : $floatData\n")
                textView.append("dateData : $dateData\n")
            }
        }
        button2.setOnClickListener {
            val sdf = SimpleDateFormat("yyyy-MM-dd",Locale.getDefault())
            val now = sdf.format(Date())

            val cv1 = ContentValues()
            cv1.put("textData","문자열3")
            cv1.put("intData",300)
            cv1.put("floatData",33.33)
            cv1.put("dateData",now)

            val cv2 = ContentValues()
            cv2.put("textData","문자열4")
            cv2.put("intData",400)
            cv2.put("floatData",44.44)
            cv2.put("dateData",now)

            val uri = Uri.parse("content://kr.co.softcampus.dbprovider")
            contentResolver.insert(uri,cv1)
            contentResolver.insert(uri,cv2)

            textView.text = "저장완료"
        }
        button3.setOnClickListener {
            val cv = ContentValues()

            cv.put("textData","문자열100")
            val where = "idx = ?"
            var args = arrayOf("idx = ?")

            val uri = Uri.parse("content://kr.co.softcampus.dbprovider")

            contentResolver.update(uri,cv,where,args)

            textView.text = "수정완료"
        }

        button4.setOnClickListener {
            val where = "idx = ?"
            val args = arrayOf("1")

            val uri = Uri.parse("content://kr.co.softcampus.dbprovider")

            contentResolver.delete(uri,where,args)

            textView.text = "삭제완료"

        }

    }
}

 

 

728x90

'안드로이드 > 데이터 입출력' 카테고리의 다른 글

안드로이드 Preferences Screen  (0) 2022.06.23
안드로이드 Preferences  (0) 2022.06.23
안드로이드 sqlite 2  (0) 2022.06.23
안드로이드 sqlite 1  (0) 2022.06.23
안드로이드 assets  (0) 2022.06.22