이동식 저장소

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_NAMEBUCKET_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