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
[Philipp@Youtube] Uris (Unique Resource Identifier) – Android Basics 2023
Comments