이번 포스팅에서는 Android 애플리케이션에서 Contents Provider
를 만들어서 활용하는 방법에 대해 알아보겠습니다. Contents Provider
는 애플리케이션 간에 데이터를 공유할 수 있도록 돕는 중요한 구성 요소 중 하나입니다. 이 글에서는 간단한 Contacts
정보 저장소를 구현해보고, 이를 애플리케이션에서 활용하는 과정을 Kotlin 예제와 함께 설명합니다.
Contents Provider란?
Contents Provider
는 Android의 주요 데이터 저장 메커니즘 중 하나로, 애플리케이션 간에 데이터를 안전하게 공유할 수 있게 해주는 기능입니다. 예를 들어, 기본 연락처 애플리케이션에서 연락처 정보를 다른 애플리케이션에서도 사용할 수 있게 하는 방식이 그 예입니다. Contents Provider
를 통해 데이터베이스, 파일 시스템 등의 저장소에 있는 데이터를 다른 애플리케이션에서 사용할 수 있습니다.
Contents Provider
를 사용하려면 데이터에 접근하기 위한 URI를 정의하고, 이를 통해 데이터를 조회, 삽입, 삭제, 수정할 수 있는 기능을 제공합니다.
Contents Provider 구현하기
이번 예제에서는 간단한 연락처 정보를 저장하고 제공하는 ContactsProvider
를 만들어 보겠습니다. 이를 통해 Content Provider
의 기본 기능을 이해할 수 있을 것입니다.
1. Content Provider 생성
먼저 새로운 클래스를 생성하여 ContactsProvider
를 구현합니다. 이 클래스는 ContentProvider
를 상속받고, 필요한 메서드를 오버라이드하여 기능을 정의합니다.
package com.example.mycontacts
import android.content.ContentProvider
import android.content.ContentUris
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.net.Uri
import android.util.Log
class ContactsProvider : ContentProvider() {
companion object {
const val AUTHORITY = "com.example.mycontacts.provider"
val CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY/contacts")
private const val CONTACTS = 1
private const val CONTACT_ID = 2
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
addURI(AUTHORITY, "contacts", CONTACTS)
addURI(AUTHORITY, "contacts/#", CONTACT_ID)
}
}
private lateinit var dbHelper: DatabaseHelper
override fun onCreate(): Boolean {
dbHelper = DatabaseHelper(context!!)
return true
}
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? {
val db = dbHelper.readableDatabase
return when (uriMatcher.match(uri)) {
CONTACTS -> db.query("contacts", projection, selection, selectionArgs, null, null, sortOrder)
CONTACT_ID -> {
val id = ContentUris.parseId(uri)
db.query("contacts", projection, "_id=?", arrayOf(id.toString()), null, null, sortOrder)
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val db = dbHelper.writableDatabase
val id = db.insert("contacts", null, values)
if (id > 0) {
val insertedUri = ContentUris.withAppendedId(CONTENT_URI, id)
context?.contentResolver?.notifyChange(insertedUri, null)
return insertedUri
}
throw IllegalArgumentException("Failed to insert row into $uri")
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
val db = dbHelper.writableDatabase
val count = when (uriMatcher.match(uri)) {
CONTACTS -> db.delete("contacts", selection, selectionArgs)
CONTACT_ID -> {
val id = ContentUris.parseId(uri)
db.delete("contacts", "_id=?", arrayOf(id.toString()))
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
context?.contentResolver?.notifyChange(uri, null)
return count
}
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int {
val db = dbHelper.writableDatabase
val count = when (uriMatcher.match(uri)) {
CONTACTS -> db.update("contacts", values, selection, selectionArgs)
CONTACT_ID -> {
val id = ContentUris.parseId(uri)
db.update("contacts", values, "_id=?", arrayOf(id.toString()))
}
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
context?.contentResolver?.notifyChange(uri, null)
return count
}
override fun getType(uri: Uri): String? {
return when (uriMatcher.match(uri)) {
CONTACTS -> "vnd.android.cursor.dir/vnd.$AUTHORITY.contacts"
CONTACT_ID -> "vnd.android.cursor.item/vnd.$AUTHORITY.contacts"
else -> throw IllegalArgumentException("Unknown URI: $uri")
}
}
private class DatabaseHelper(context: android.content.Context) : SQLiteOpenHelper(context, "contacts.db", null, 1) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, phone TEXT NOT NULL);")
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS contacts")
onCreate(db)
}
}
}
위 코드는 ContactsProvider
를 구현한 것으로, 간단한 연락처 정보를 저장, 조회, 수정, 삭제할 수 있는 기능을 제공합니다. DatabaseHelper
클래스는 SQLite 데이터베이스를 생성하고 관리합니다.
2. Manifest 파일 설정
Contents Provider
를 사용하려면 AndroidManifest.xml 파일에 이를 등록해야 합니다. 아래와 같이 <provider>
태그를 추가합니다.
<provider
android:name=".ContactsProvider"
android:authorities="com.example.mycontacts.provider"
android:exported="true" />
3. Content Provider 활용하기
Content Provider
를 사용해 데이터를 삽입하거나 조회하는 방법을 알아보겠습니다. 다른 애플리케이션이나 같은 애플리케이션의 다른 Activity에서 ContentResolver
를 사용해 접근할 수 있습니다.
데이터 삽입
다음은 ContactsProvider
에 새 연락처를 삽입하는 코드입니다.
val values = ContentValues().apply {
put("name", "John Doe")
put("phone", "123-456-7890")
}
val newContactUri = contentResolver.insert(ContactsProvider.CONTENT_URI, values)
데이터 조회
다음은 ContactsProvider
에서 모든 연락처를 조회하는 코드입니다.
val cursor = contentResolver.query(ContactsProvider.CONTENT_URI, null, null, null, null)
cursor?.use {
while (it.moveToNext()) {
val name = it.getString(it.getColumnIndexOrThrow("name"))
val phone = it.getString(it.getColumnIndexOrThrow("phone"))
Log.d("ContactsProvider", "Contact: $name, Phone: $phone")
}
}
위 코드에서는 ContentResolver
를 사용해 Content Provider
에 접근하고 데이터를 가져오는 방법을 보여줍니다.
마무리
이번 포스팅에서는 Contents Provider
를 구현하고 이를 활용하는 방법에 대해 알아보았습니다. Contents Provider
는 애플리케이션 간에 데이터를 안전하게 공유할 수 있는 강력한 도구입니다. 이를 잘 활용하면 데이터 관리와 공유를 효율적으로 할 수 있습니다.
예제 코드와 설명을 통해 Contents Provider
의 기본적인 동작 원리와 구현 방법을 이해하셨길 바랍니다.
'Android' 카테고리의 다른 글
Android REST API(Retrofit) 연동 - 네트워크 통신과 데이터 파싱 (0) | 2024.11.22 |
---|---|
Android - Room 라이브러리로 SQLite 데이터베이스 구축 및 CRUD 구현하기 (0) | 2024.11.21 |
Android Content Provider - 애플리케이션 간 데이터 공유 (0) | 2024.11.19 |
Android JobScheduler, WorkManager - 서비스의 최적화(Optimize Service) (0) | 2024.11.18 |
Android - Foreground Service(백그라운드 작업), Bound Service(애플리케이션 간 상호작용) (0) | 2024.11.17 |