Uri 在 android 系統中,其實就是一個指向特定資源的識別路徑,除了識別用途外,還有安全性的考量。

個別的 app 在 android 系統中,都存在一個沙盒 (sand box) 中,系統會避免資源 (尤其是指檔案) 的真實路徑曝露,對於需要分享的資源,則會以 uri 的型式對外提供。

Uri 的種類

resource uri

表示在專案結構中的某個特定資源,如果我們把 sample.jpg 這個圖片放到 res/drawable/ 中,就可以用以下程式碼來取得其 uri,其中 parse() 方法可以把 uri 字串解析成 Uri 物件。

val uri = Uri.parse("android.resource://$packageName/drawable/sample")

file uri

表示儲存在 internal storage (內部儲存空間) 的檔案資源,內部儲存空間只有 app 自己能讀寫,無法分享給其他 app 使用

承繼之前的程式碼,以下是取得 file uri 字串的方式

val sampleBytes = contentResolver.openInputStream(uri)?.use {
		it.readBytes()
}
println("Sample size: ${sampleBytes?.size}")


var file = File(filesDir, "sample.jpg")
FileOutputStream(file).use {
		it.write(sampleBytes)
}
// 產生file uri
// 通常只能存取 app 本身的 file (因為權限)
println(file.toUri())
// 這會印出 // file://data/user/0/app.kirin.uridemo/files/sample.jpg

content uri

這是最常用到的 uri 類型,content uri 是可以分享給其他 app 的資源,可以是通訊錄、影片、照片…等,其他的 app 可以透過 ContentProvider 來取得所需的資源。

至於要如果使用,就那是另一個主題了,請參閱以下文章:

Android Developers Guide: 內容供應器基本概念

data uri

很少用到,這是代表某種資料的 uri,可以是字串,可以是數字

// 字串型態的 data uri
val dataUri = Uri.parse("data:text/plain;charset=UTF-8,Hello%20Android")

Uri 的結構

URI,由授權名稱 (authority) 及 路徑 (path) 組成,作為存取 ContentProvider 的唯一識別符號,其標準格式如下:

content://com.example.app.provider/todos

其中 content 表示 Uri 的類別, com.example.app.provider 就是 authority (資料的來源), todos 則為 path (資料存取的識別路徑)。

Uri 其實跟我們常用的 url 很像

https://kirin.app/sample_page

其中 https 表示 url 的類別 (協定), kirin 就是 authority (資料的來源), sample_page 則為 path (資料存取的識別路徑)。

參考資料

Android Developers Reference: Uri

[CSDN] Android中的Uri详解

[Philipp@Youtube] Uris (Unique Resource Identifier) – Android Basics 2023

Last modified: 2023 年 12 月 31 日

Author

Comments

Write a Reply or Comment

Your email address will not be published.