昨天在顯示圖片的部份卡關,原本打算用contentResolver.insert()
建立相片uri
,然後用contentResolver.query()
取得相片uri
,不過contentResolver.query()
一直得不到想要的內容,只好先送;另一種方法是把contentResolver.insert()
取得的uri
先存起來,然後再顯示,不過這樣不符合個人美學所以作罷。
先介紹一下ContentResolver
,ContentResolver
就是用SQLite
的形式,去操作其他應用程式的增加、修改、查詢、刪除,所以在使用上會不太直覺,網路上也都是講取得複數資料,例如全部的連絡人,或是全部的圖片,但這次我們只要取得單張圖片的uri
就好,以下是ContentResolver.query()
的參數解說:
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
null
MediaStore.Images.ImageColumns.DISPLAY_NAME
跟ContentResolver
說我們要找檔案名稱,後面跟他說檔案名稱叫什麼 = '003.jpg'
ASC
或DESC
都可以val uriQuery = contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
"${MediaStore.Images.ImageColumns.DISPLAY_NAME} = '003.jpg'",
null,
"${MediaStore.Images.ImageColumns.DATE_ADDED} DESC"
) ?: return@registerForActivityResult
找到檔案後,因為ContentResolver.query()
沒有提供uri
,所以我們先取得圖片Id
,再用ContentUris.withAppendedId()
來組合出檔案uri
,需要注意的地方是一定要先加上uriQuery.moveToFirst()
,把cursor
的位置移到第一位,不然會報IndexOutOfBoundsException
的錯誤
uriQuery.moveToFirst()
取得圖片的Id。
val pictureId = uriQuery.getLong(uriQuery.getColumnIndex(MediaStore.Images.ImageColumns._ID))
因為Id
是整數,所以使用ContentUris.withAppendedId()
把路徑和Id
組合成uri
,如果是字串的話就要改用Uri.withAppendedPath()。
val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, pictureId)
最後就能得到圖片完整uri
,這邊的範例是把圖片用ImageView
顯示出來。
aclIvMediaStorePicture.setImageURI(uri)
全部的程式碼是這樣
private val takePictureResultLauncher =
registerForActivityResult(ActivityResultContracts.TakePicture()) { isTakePicture ->
if (!isTakePicture) {
Log.d("maho", "拍照建立檔案失敗")
return@registerForActivityResult
}
val uriQuery = contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
"${MediaStore.Images.ImageColumns.DISPLAY_NAME} = '003.jpg'",
null,
"${MediaStore.Images.ImageColumns.DATE_ADDED} DESC"
) ?: return@registerForActivityResult
uriQuery.moveToFirst()
val pictureId = uriQuery.getLong(uriQuery.getColumnIndex(MediaStore.Images.ImageColumns._ID))
val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, pictureId)
aclIvMediaStorePicture.setImageURI(uri)
}