iT邦幫忙

2021 iThome 鐵人賽

DAY 30
0
自我挑戰組

社畜轉行之旅,30天Kotlin學習筆記系列 第 30

Day 30 | ContentProvider

可以使用ContentProvider將資料庫分享給其他應用程式共享資訊,或從其他應用程式操作資料

ContentProvider分為Provider(提供者)與Resolver(解析者)兩個角色,Provider定義授權的名稱並提供內容讓Resolver操作,Resolver則向特定授權名稱的Provider要求內容操作。

應用程式會以特定格式的Uri類別表示,開發者透過授權名稱(Authority)訪問其他應用程式的內容

Untitled

  • Scheme為前綴字,在ContentProvider都用content://
  • Authority為自定義的授權名稱,用於識別內容來源
  • Path為內容路徑,用於區分不同資料的存取,可不填
  • ID為內容的為一識別標籤,可將資料庫中每筆紀錄建立獨立的Uri

建立ContentProvider

  1. File→New→Other→Content Provider

    Untitled

  2. 修改名稱與授權名稱後點Finish

    Untitled

  3. AS會自動產生ContentProvider需要的檔案,AndroidManifest.xml也會自動增加Receiver的資訊

    Untitled

提供與解析ContentProvider

實作Provider

class MyContentProvider : ContentProvider() {
    private lateinit var dbrw: SQLiteDatabase

    //Step1:當Resolver要求操作資料時,Provider會先進入onCreate(),需先開啟資料庫
    override fun onCreate(): Boolean {
        val context = context ?: return false
        //取得資料庫實體
        dbrw = MyDBHelper(context).writableDatabase
        return true
    }

    //Step2:Resolver要求新增資料,則取得它給予的資料並新增於資料庫
    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        //取出其他應用程式給予的book資料
        val book = values ?: return null
        //將資料薪曾於資料庫病回傳此筆紀錄的ID
        val rowID = dbrw.insert("myTable", null, book)
        //回傳此筆紀錄的Uri
        return Uri.parse("content://com.italkutalk.lab16/book/$rowID")
    }

    override fun update(
        uri: Uri, values: ContentValues?, selection: String?,
        selectionArgs: Array<String>?
    ): Int = 0
    
    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0

    override fun getType(uri: Uri): String? = null

    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? = null

}

實作Resolver

Provider完成後,需建立另一個應用程式作為Resolver,Resolver需在AndroidManifest.xml定義Provider的package名稱。

Untitled

<queries>
        <package android:name="com.italkutalk.lab16"/>
</queries>

接著撰寫程式碼,實作Resolver以新增資料

//Step1:建立ContentValues物件,用於存放要新增的資料
val values = ContentValues()
//book欄位填入恐龍書
values.put("book", "恐龍書")
//price欄位填入1400
values.put("price", 1400)
//Step2:透過insert()放入Uri及ContentValues讓provider新增資料
val uri = Uri.parse("content://com.italkutalk.lab16")
val contentUri = contentResolver.insert(uri, values)
//Step3:判斷回傳此筆紀錄Uri是否為null,以確認資料新增是否成功
if (contentUri != null)
    Toast.makeText(this, "新增:恐龍書,價格:1400",Toast.LENGTH_LONG).show()
else
    Toast.makeText(this, "新增失敗",Toast.LENGTH_LONG).show()

上一篇
Day 29 | SQLite資料庫(四)
系列文
社畜轉行之旅,30天Kotlin學習筆記30

尚未有邦友留言

立即登入留言