일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- AWS
- Kotlin
- GitHub
- Compose
- 코루틴
- relay
- MiTweet
- Rxjava
- android
- Coroutines
- Gradle
- 프로그래머스
- livedata
- 쿠링
- architecture
- 백준
- Codeforces
- boj
- TEST
- 암호학
- Coroutine
- Python
- 코드포스
- Hilt
- MyVoca
- pandas
- ProGuard
- androidStudio
- activity
- textfield
- Today
- Total
이동식 저장소
MiTweet 개발일지 3 본문
커스텀 갤러리의 사진 선택 기능을 완성하였다.
선택한 사진을 트윗 작성 화면에서 해제 가능
지금까지는 선택을 해제하기 위해 커스텀 갤러리에 들어가야 했다. 사진 미리보기 뷰에 삭제 버튼을 붙여서 사진을 쉽게 지울 수 있도록 했다.
이미지가 중복되던 버그 수정
커스텀 갤러리에 특정 이미지가 중복으로 나타나던 버그를 해결했다. 갤러리에서 사진을 가져올 때 쿼리문에 ``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 |