이동식 저장소

MiTweet 개발일지 3 본문

프로젝트/MiTweet

MiTweet 개발일지 3

해스끼 2020. 8. 16. 17:18

커스텀 갤러리의 사진 선택 기능을 완성하였다.

선택한 사진을 트윗 작성 화면에서 해제 가능

지금까지는 선택을 해제하기 위해 커스텀 갤러리에 들어가야 했다. 사진 미리보기 뷰에 삭제 버튼을 붙여서 사진을 쉽게 지울 수 있도록 했다.

X 버튼을 누르면 사진이 지워진다.

이미지가 중복되던 버그 수정

커스텀 갤러리에 특정 이미지가 중복으로 나타나던 버그를 해결했다. 갤러리에서 사진을 가져올 때 쿼리문에 ``MediaStore.Images.Media.DATA``를 사용했는데, 아마도 이 필드가 원인이지 않을까 추정한다. 어차피 Android Q(10)부터는 Deprecated된 필드라서 새로운 방법을 찾아야 했다.

 

쿼리 결과로 얻은 ``cursor``를 다음과 같이 순회했다.

val externalUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val imageCursor = contentResolver.query(externalUri, projection, null, null, sortOrder)
imageCursor?.use {
    	val columnIndexId = it.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
        while (it.moveToNext()) {
    	    val imageId = it.getString(columnIndexId)
    	    photos.add(PhotoItem(Uri.withAppendedPath(externalUri, imageId)))
    }
}

추가한 Uri를 로그로 찍어 보면 ``/external/images/media/29`` 형태의 값이 나온다. 기존 코드에서는 ``MediaStore.Images.Media.DATA`` 필드를 이용하여 파일의 절대 경로를 얻었는데, Android 10에서는 ``InputStream``을 열어 파일에 접근해야 한다. 모든 파일 접근을 ``MediaStore``를 통하게 하려는 의도라고 한다.

 

따라서 Twitter4j에서 ``InputStream``을 열어 파일을 업로드하도록 코드를 수정했다.

// before
twitter?.uploadMedia(photoItem.imageUri.toFile())?.mediaId?.let {
	mediaIdList.add(it)
}

// after
contentResolver.openInputStream(photoItem.imageUri).use { stream ->
	twitter?.uploadMedia("", stream)?.mediaId?.let { id ->
		mediaIdList.add(id)
	}
}

갤러리에서 폴더별로 사진 분류

사진을 폴더별로 분류하여 볼 수 있게 수정하려면 우선 폴더의 목록을 알아야 한다. ``MediaStore.Images.Media.BUCKET_DISPLAY_NAME`` 필드를 이용하여 query를 날리면 이미지가 들어있는 각 폴더의 이름을 알 수 있다. 그런데 폴더의 이름이 중복될 수도 있기 때문에 쿼리할 때 ``MediaStore.Images.Media.BUCKET_ID``를 추가했고, ``BUCKET_DISPLAY_NAME``과 ``BUCKET_ID`` 쌍의 ``HashMap``을 만들어 나중에 사용할 수 있도록 했다. 참고로 ``BUCKET_ID``는 음수를 포함하여 임의의 정수값이 될 수 있다. 

    fun getImageBuckets(): List<String> {
        val buckets = mutableSetOf<String>()
        val externalUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        val projection =
            arrayOf(MediaStore.Images.Media.BUCKET_DISPLAY_NAME, 
                    MediaStore.Images.Media.BUCKET_ID)

        val cursor = contentResolver.query(externalUri, projection, null, null, null)
        cursor?.use {
            val bucketNameColumn = cursor.getColumnIndexOrThrow(projection[0])
            val bucketIdColumn = cursor.getColumnIndexOrThrow(projection[1])
            while (it.moveToNext()) {
                val bucketName = cursor.getString(bucketNameColumn)
                val bucketId = cursor.getLong(bucketIdColumn)
                buckets.add(bucketName)
                bucketHashMap[bucketName] = bucketId
            }
        }
        val bucketList = buckets.toMutableList()
        bucketList.sort()
        bucketList.add(0, "모든 사진")
        return bucketList
    }

폴더 상관없이 모든 사진을 보고 싶을 경우를 위해 리스트 앞에 ``모든 사진``을 추가하였다.

 

이제 폴더를 선택할 수 있도록 툴바에 ``Spinner``를 추가하자.

스피너를 터치하면 폴더 목록이 나오고, 해당 폴더의 사진만 볼 수 있다. 이때 특정 폴더의 사진만 불러올 수 있도록 쿼리문을 확장하였다.

 

버그 수정

X 버튼으로 이미지를 모두 지웠을 때 미리보기 뷰가 사라지지 않던 현상을 수정하였다.

TODO

미리보기 화면에서 사진을 터치하여 편집할 수 있도록 하기

투표를 트윗에 작성할 수 있도록 하기 - 이미지와 함께 작성 불가능?

'프로젝트 > MiTweet' 카테고리의 다른 글

MiTweet 개발일지 6  (0) 2020.08.28
MiTweet 개발일지 5  (0) 2020.08.27
MiTweet 개발일지 4  (0) 2020.08.19
MiTweet 개발일지 2  (0) 2020.08.13
MiTweet 개발일지 1  (0) 2020.08.10
Comments