iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
Mobile Development

重新瞭解Android硬體控制系列 第 9

110/13 - 把照片儲存在Pictures/應用程式名稱資料夾 - 3

  • 分享至 

  • xImage
  •  

各位鐵人\教師節快樂/

昨天在顯示圖片的部份卡關,原本打算用contentResolver.insert()建立相片uri,然後用contentResolver.query()取得相片uri,不過contentResolver.query()一直得不到想要的內容,只好先送;另一種方法是把contentResolver.insert()取得的uri先存起來,然後再顯示,不過這樣不符合個人美學所以作罷。

先介紹一下ContentResolverContentResolver就是用SQLite的形式,去操作其他應用程式的增加、修改、查詢、刪除,所以在使用上會不太直覺,網路上也都是講取得複數資料,例如全部的連絡人,或是全部的圖片,但這次我們只要取得單張圖片的uri就好,以下是ContentResolver.query()的參數解說:

  1. 是從什麼應用程式找檔案,因為要找圖片,所以使用MediaStore.Images.Media.EXTERNAL_CONTENT_URI
  2. 是指定檔案類型,但我們全部的檔案都找,所以給null
  3. 是尋找條件,所以用MediaStore.Images.ImageColumns.DISPLAY_NAMEContentResolver說我們要找檔案名稱,後面跟他說檔案名稱叫什麼 = '003.jpg'
  4. 窩不知道
  5. 排序方式,因為只有找一個檔案,所以ASCDESC都可以
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)
    }

上一篇
110/12 - 把照片儲存在Pictures/應用程式名稱資料夾 - 2
下一篇
110/14 - EasyPermissions與他的快樂伙伴
系列文
重新瞭解Android硬體控制14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言