**AndroidManifest.xml**
에 명시해야 한다.<queries>
<provider android:authorities="kr.co.softcampus.dbprovider" />
</queries>
viewBinding{
enabled = true
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/ButtonSelectData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="select" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/textViewResult"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="textView" />
</LinearLayout>
</ScrollView>
</LinearLayout>
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
class DBHelper(context: Context) : SQLiteOpenHelper(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,
doubleData real not null,
dateData date not null
)
""".trimIndent()
db?.execSQL(sql)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
TODO("Not yet implemented")
}
}
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.test.android75_contentproviderapp1.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.run {
ButtonSelectData.run{
val sql = "select * from TestTable"
val dbHelper = DBHelper(this@MainActivity)
val cursor = dbHelper.writableDatabase.rawQuery(sql,null)
textViewResult.text = ""
while (cursor.moveToNext()){
val idx1 = cursor.getColumnIndex("idx")
val idx2 = cursor.getColumnIndex("textData")
val idx3 = cursor.getColumnIndex("intData")
val idx4 = cursor.getColumnIndex("doubleData")
val idx5 = cursor.getColumnIndex("dateData")
val idx = cursor.getInt(idx1)
val textData = cursor.getString(idx2)
val intData = cursor.getInt(idx3)
val doubleData = cursor.getDouble(idx4)
val dateData = cursor.getString(idx5)
textViewResult.append("idx : ${idx}\n")
textViewResult.append("textData : ${textData}\n")
textViewResult.append("intData : ${intData}\n")
textViewResult.append("doubleData : ${doubleData}\n")
textViewResult.append("dateData : ${dateData}\n\n")
}
dbHelper.close()
}
}
}
}
URI Authorities를 안붙이면 만들 수가 없음
-> content provider의 목적이 다른 어플리케이션에서 쓰라고 존재하는 것이기 때문에 꼭 설정을 해야지만 만들 수 있음
lateinit var sqliteDatabase: SQLiteDatabase
// delete
// 두 번째 : 조건절
// 세 번째 : 조건절의 ?에 설정될 값 배열
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
val cnt = sqliteDatabase.delete("TestTable", selection, selectionArgs)
return cnt
}
// 칼럼의 데이터 타입을 MIME 타입 형태로 문자열을 만들어 반환하는 메서드
// 알려줄 필요가 없다면 null을 반환한다.
override fun getType(uri: Uri): String? {
return null
}
// insert
// 두번째 매개변수 : 저장할 데이터의 칼럼의 이름과 값이 담긴 객체
override fun insert(uri: Uri, values: ContentValues?): Uri? {
// 저장한다.
sqliteDatabase.insert("TestTable",null,values)
return uri
}
// Content Provider 객체가 생성되면 자동으로 호출되는 메서드
// 데이터 베이스에 접근할 수 있는 객체를 생성하고
// 접속에 성공하면 true, 실패하면 false를 반환하도록 구현해준다.
override fun onCreate(): Boolean {
val dbHelper = DBHelper(context!!)
sqliteDatabase = dbHelper.writableDatabase
// 접속에 실패하면 false를 반환한다
if(sqliteDatabase == null){
return false
}
return true
}
// select
// 두 번째 : 가져올 컬럼 목록
// 세 번째 : 조건절
// 네 번째 : 조건절 ?에 설정될 값
// 다 번째 : 정렬 기준
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
): Cursor? {
val cursor = sqliteDatabase.query("TestTable", projection, selection, selectionArgs, null, null, sortOrder)
return cursor
}
// 두 번째 : 변경할 컬럼의 이름과 값이 있는 ContentValues 객체
// 세 번째 : 조건절
// 네 번째 : 조건절의 ? 에 설정될 값들의 배열
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
): Int {
val cnt = sqliteDatabase.update("TestTable", values, selection, selectionArgs)
return cnt
}
package com.test.android75_contentproviderapp2
import android.content.ContentValues
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.test.android75_contentproviderapp2.databinding.ActivityMainBinding
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
activityMainBinding.run {
button.run{
setOnClickListener {
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val now = sdf.format(Date())
// 저장할 데이터를 ContentValues에 담아 준다.
val cv1 = ContentValues()
cv1.put("textData", "문자열1")
cv1.put("intData", 100)
cv1.put("doubleData", 11.11)
cv1.put("dateData", now)
val cv2 = ContentValues()
cv2.put("textData", "문자열2")
cv2.put("intData", 200)
cv2.put("doubleData", 22.22)
cv2.put("dateData", now)
// Content Provider의 이름을 가지고 있는 Uri 객체를 생성한다.
val uri = Uri.parse("content://com.test.dbprovider")
// Content Provider를 이용할 수 있는 객체를 통해 사용한다.
contentResolver.insert(uri, cv1)
contentResolver.insert(uri, cv2)
textView.text = "저장 완료"
}
}
button2.setOnClickListener {
val uri = Uri.parse("content://com.test.dbprovider")
// Content Provider를 통해서 데이터를 가져온다.
// 두 번째 : 가져올 컬럼 목록. null을 설정하면 모든 컬럼
// 세 번째 : 조건절
// 네 번째 : 조건절의 ?에 설정된 값 배열
// 다섯 번째 : 정렬 기준 컬럼 목록
val cursor = contentResolver.query(uri, null, null, null, null)
textView.text = ""
while (cursor?.moveToNext()!!){
val idx1 = cursor?.getColumnIndex("idx")
val idx2 = cursor?.getColumnIndex("textData")
val idx3 = cursor?.getColumnIndex("intData")
val idx4 = cursor?.getColumnIndex("doubleData")
val idx5 = cursor?.getColumnIndex("dateData")
val idx = cursor.getInt(idx1!!)
val textData = cursor.getString(idx2!!)
val intData = cursor.getInt(idx3!!)
val doubleData = cursor.getDouble(idx4!!)
val dateData = cursor.getString(idx5!!)
textView.append("idx : ${idx}\n")
textView.append("textData : ${textData}\n")
textView.append("intData : ${intData}\n")
textView.append("doubleData : ${doubleData}\n")
textView.append("dateData : ${dateData}\n\n")
}
}
button3.setOnClickListener {
val cv1 = ContentValues()
cv1.put("textData", "새로운 문자열")
val where = "idx = ?"
val args = arrayOf("1")
val uri = Uri.parse("content://com.test.dbprovider")
// 수정한다.
contentResolver.update(uri, cv1, where, args)
textView.text = "수정 완료"
}
button4.run{
setOnClickListener {
val where = "idx = ?"
val args = arrayOf("1")
val uri = Uri.parse("content://com.test.dbprovider")
contentResolver.delete(uri, where, args)
textView.text = "삭제 완료"
}
}
}
setContentView(activityMainBinding.root)
}
}