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 |