
오늘은 컴터를 켰더니 떠~억 네잎 크로바가 나왔다. 행운이 가득 하길 바라며... 오늘도 잘 살았으니, 감사합니다.
빌코리아의 홈페이지 입니다.
앱을 만들어 사용하다 보면 간혹 이미지를 받아와서 사용하게 되는 경우가 있게 된다. 그런데, 온라인으로 firebase 을 활용해 저장을 해 보려 하니, 저장 하고 받아오는 속도가 문제가 되는 것 같다. 여기서 사용되는 이미지는 그냥 참고를 위한 간략한 정보로만 사용되기 때문에 그 크기를 줄여 성능 이슈를 보완하는 것으로 방향을 선택 했다.
먼저 이미지는 어떻게 수집할 것 인가 ? 이 부분은 이전 게시한 글을 참고하길 바라며
https://billcorea.tistory.com/196
안드로이드 앱 만들기 : Jetpack Compose 에서 프로필 이미지 저장해 보기
앱을 만들다 보면 프로필 가져오기 기능을 구현해 보는 경우가 간혹 생긴 게 된다. 오늘은 compose을 이용한 구현을 하는 과정에서 갤러리에서 이미지를 불러와서 프로필 사진으로 저장하는 과정
billcorea.tistory.com
오늘은 불러온 이미지를 줄이는 방법에 대한 이야기를 해 볼까 한다.
bitmap.value?.let { bitmap ->
var btm = bitmap
val baos = ByteArrayOutputStream()
btm?.compress(
Bitmap.CompressFormat.PNG,
100,
baos
)
val b: ByteArray = baos.toByteArray()
jobRefImage.value = Base64.encodeToString(b, Base64.DEFAULT)
}먼저 그냥 compress 을 해 보는 방법이다. 구글 검색을 통해서 얻은 내용으로는 compress 을 하는 건 이미지를 압축하기는 하지만, 크기가 변하지는 않는다. 요새 폰의 카메라른 워낙 성능이 좋아서 사진 크기가 5Mbyte을 넘어가는 경우도 있는데, 그 크기가 줄어 들지 않는 것이다. 그래서 이걸 그대로 byte type 으로 변환 해서 저장을 하고자 했더니, 모래시계만 뱅글 뱅글... 끝나지가 않았다.
private fun resizeBitmap(bitmap: Bitmap): Bitmap? {
val resizeWidth = 512
val aspectRatio = bitmap.height.toDouble() / bitmap.width.toDouble()
val targetHeight = (resizeWidth * aspectRatio).toInt()
val result: Bitmap = Bitmap.createScaledBitmap(bitmap, resizeWidth, targetHeight, false)
if (result != bitmap) {
bitmap.recycle()
}
return result
}
// 실제 함수 호출은 이렇게 해서 위에서 작성한 코드를 대체 하였다.
bitmap.value?.let { bitmap ->
var btm = resizeBitmap(bitmap)
val baos = ByteArrayOutputStream()
btm?.compress(
Bitmap.CompressFormat.PNG,
100,
baos
)
val b: ByteArray = baos.toByteArray()
jobRefImage.value = Base64.encodeToString(b, Base64.DEFAULT)
}그래서 찾은 방법이 createScaledBitmap 함수 이다. 그 사용 방법은 위 내용과 같다. 이렇게 하면 이미지의 크기를 내가 원하는 크기로 조절하기 때문에 사이즈도 줄어 들고 firebase realtime database 에 byte type 을 저장을 하더라도 성능이 떨어지지 않는 것을 알게 되었다.

오늘도 메일이 왔다... 검증을 요청한 앱이 정책 위반으로 검증을 통과하지 못했다는... ㅠㅠ;;



연속 3일째 도전 중이기는 하나... playstore의 검증팀은 깐깐한가 보다...
1. 검증을 통과하지 못하는 이유? 메일의 내용은 그것이다. 사용자가 메시지나 정보를 등록하는 앱의 경우 (UGC라고 하던데)에는 불건전한 게시물이나, 채팅 내용 등이 발생할 것이 예상되는 경우, 그런 사용자나, 게시물에 대한 신고 기능을 구현하고
2. 관리자로 하여금 선량한 관리자의 의무를 다하라고 하는 내용으로
경고 안내문이 오고, 게시를 요청한 앱의 검증은 실패가 된다.
3. 이런 경우라고 해도, 이전 버전이 playstore에 등록되어 있다면, 그것이 삭제되거나 하지는 않는다.
다만, 지속적으로 이에 대한 보완을 행하지 않는 다면, 최종적으로는 앱이 퇴출될 수도 있으니 신속하게 보완해서 재 반영을 요청하여야 한다.
2022.06.23 수정
이제 통과되었다. UGC 가 있는 화면 마다 스팸이나, 블랙유저 신고를 할 수 있는 버튼을 달아야 하고, 알림 다이얼로그의 문구 하나도 각 상황에 맞게 표시를 해야만 검증을 통과하게 된다.
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416
다국어 일자리 구하기 (multi language) - Google Play 앱
한국에서 일자리를 구하는 사람들에게 한국어가 익숙하지 않아도 찾을 수 있도록 지원할 예정 입니다.여러 나라 사람들과 채팅을 할 수 있습니다.
play.google.com
https://blog.protein.tech/document-your-kotlin-android-project-using-dokka-a4129a461203
Document Your Kotlin-Android Project Using Dokka
Keeping track of source code is challenging for any software project. It's even more challenging when you're working on an open-source…
blog.protein.tech
개발자로 살면서 제일 징그럽게 싫었던 것 중 하나, 문서화
제일 필요하다고 생각했던 것도 문서화...
다양한 방법의 문서화 방법이 있을 것이라고 생각이 되기는 한다. 나의 경우는 코드 작업을 하면서 최대한 기억을 남겨 두기 위한 노력을 했었다. 그래도 잘 되지 않았던 것이 문서화를 하는 것이다.
구글링을 하다 발견한 문서 하나의 링크를 걸어 두었다. 두고두고 배워서 정리를 하리라 다짐하며...
앱의 기능 중에서 메시지 전송을 위하 기능을 구현 하고 있으나, 난관에 봉착했다. FCM 을 통해서 안드로이드 앱에서 message 전송을 하고 싶어서 매번의 릴리즈를 하고 있지만, 전송이 되지 않는 다. debug 상태에서는 잘 되는 데...
왜 일까 ?
코드 난독화를 하기 위해서 설정을 한 것이 문제인 건가 ?
내일은 알게 되기를 바라며... 오늘은 이만...

2022.06.25
이 문제를 테스트 하기 위해서 playstore 에 패치 등록을 5번 했다. ㅋ~
그래서 확인된 이슈는 코드 난독화 가 이슈의 발생지임을 알게 되었다. 그럼 이제 그것을 어떻게 해결할 것인가 ?
일단 정확하게 알지 못하는 현재는 코드 난독화를 하지 않는 것으로 해서 적용해 두었다. 다음에는 꼭 코드 난독화가 적용된 앱을 출시해 보아야 겠다.
buildTypes {
debug {
buildConfigField "Boolean", "DEBUG_MODE", "true"
resValue("string", "PORT_NUMBER", "8081")
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
buildConfigField "Boolean", "DEBUG_MODE", "false"
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}현재 적용중인 gradle 파일의 일부분... minifyEnabled 을 다음에는 꼭 true 로 설정하게 될 길 바라며....
오늘은 간략하게 나마, ArrayList 의 정렬 방법을 찾아 보았다.
chatMessageItem.content = respString + "\n( " + chatMessageItem.content + " )"
chatMessageItem.locale = sp.getString("languageCode", "kr").toString()
chatMesgItems.add(chatMessageItem)
if (isSort) {
chatMesgItems.sortBy {
it.seqNo
}
}chatMessageItem 이라는 ArrayList 에 값을 넣는 순간 정렬이 필요한 경우가 생겼다. 그래서 간략하게 위 코드와 같이 정렬를 해 본다.
다만, chatMessageItems 는 Class 구조체를 가지고 있으므로 그 구조체에서 정렬할 키로 사용할 것을 잘 선택해야 한다.
여기서 보는 seqNo 는 timesequence 을 이용한 값을 key로 사용하고 그것을 정렬하는 방식으로 사용해 보았다.

그림과 같이 대화방을 의 대화 내용이 시간순으로 정렬을 해 보고자 했을 때 사용해 볼 수 있었다.