김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㄱ
  • 원격저장소
  • 로컬저장소
  • local저장소
  • KMU_WINK
  • 깃허브데스크탑
  • GitHubDesktop
  • Remote저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[안드로이드&코틀린] 중고거래앱 만들기#4, 파일 접근 권한 얻기, 갤러리에서 이미지 가져오기, floatButton, 파이어베이스 동기 처리
•App/안드로이드 with Kotlin

[안드로이드&코틀린] 중고거래앱 만들기#4, 파일 접근 권한 얻기, 갤러리에서 이미지 가져오기, floatButton, 파이어베이스 동기 처리

2022. 5. 10. 02:51

 

 

[안드로이드&코틀린] 중고거래앱 만들기#3, 프래그먼트에서 파이어베이스 연결하기, 파이어베이

[안드로이드&코틀린] 중고거래앱 만들기#2, 중고 물품 정보 리사이클러 뷰 만들기, 프래그먼트에 [안드로이드&코틀린] 중고거래앱 만들기#1, 프래그먼트 이용하여 하단메뉴바 만들기, setOnItemSelect

devforyou.tistory.com

 

# 결과물 미리보기

 파이어베이스에 data를 업로드하는 기능과, 이미지에 접근해서 파일을 가져오는 것까지 구현했다. 아직은 auth를 통한 로그인 단계와, firestore을 사용해서 이미지를 저장시키는 기능은 구현되지 않았다.

 저번시간에 생겼던 비동기처리 문제로 인해서 리스너가 사실상 실시간으로 들어오지 않는다. 이건 프로젝트를 다 만들고나서 확실하게 처리해봐야 할 것 같다. 안된다면 코루틴이라도 해서 이번 프로젝트에 완성 시켜야 할 것 같다. 학교에서 알파프로젝트를 하는데 결국 거기서도 이거랑 비슷한 문제가 발생 했기 때문이다..

 

# 구현 순서

  1. 물품 추가 xml 레이아웃 만들기
  2. 물품 추가 액티비티 만들기
  3. 갤러리 접근 권한 구현하기
  4. 갤러리에서 파일 가져오기
  5. 파이어베이스에 데이터 업로드하기

 

# 물품 추가 xml 레이아웃 만들기

물품 등록을 위한 액티비티를 구성한다. 해당 액티비티로 넘어가기 위해서는 홈프래그먼트에 버튼을 하나 추가해줘야하는데, 리사이클러뷰는 스크롤 되기 때문에 항상 같은곳에 위치할 수 있는 FloatingActionButton을 추가해준다.

app:tint="@color/white" // '+'아이콘 색 지정
android:src="@drawable/ic_baseline_add_24" // '+' 벡터 이미지
android:backgroundTint="@color/carrot_color" // 배경색

 

# 갤러리 접근 권한 구현하기

 

[안드로이드&코틀린] 앨범 만들기#3, 안드로이드 파일접근 권한 얻기, checkSelfPermission, shouldShowReque

[안드로이드&코틀린] 앨범만들기#2, 액티비티 생명주기, Activity LifeCycle, 안드로이드 라이프사이클 저번 포스팅에 이어서 정리하도록 하겠다. [안드로이드&코틀린] 앨범만들기#1, 코틀린 let, putExtra

devforyou.tistory.com

 꽤 오래만에 접근권한을 다시 사용했다. 블로그 정리해놓은게 정말 빛을 발휘하는 순간이었다. 까먹은 개념이 많았는데, 내가 정리한 글을 다시보면서 쉽게 이해 할 수 있었다.

먼저 이미지 추가 버튼을 누르면 접근 권한을 체크하는 분기점을 거친다.

private fun initAddImageButton() {
    addImageButton.setOnClickListener {
        Log.d(TAG,"addImageButton called!!")
        when {
            ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
            -> {
                // 권한이 존재하는 경우
                // TODO 이미지를 가져옴
                getImageFromAlbum()
            }
            shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
                // 권한이 거부 되어 있는 경우
                showPermissionContextPopup()
            }
            else -> {
                // 처음 권한을 시도했을 때 띄움
                requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),REQUEST_FIRST)
            }
        }
    }
}

각각의 분기점을 만들어주고, 권한이 거부되어 있는 경우에는 다이얼로그는 간단하게 커스텀하여, requestPermissions(...) 을 다시 묻도록 한다. 권한을 요청했을때, 권한이 맞다면 앨범에 접근하게 될 것이다.

 

# 앨범에서 이미지 Uri 가져오기

 

[안드로이드&코틀린] 앨범 만들기#4, 갤러리에서 이미지 가져오기, 안드로이드 SAF(Storage Access Frame

[안드로이드&코틀린] 앨범 만들기#3, 안드로이드 파일접근 권한 얻기, checkSelfPermission, shouldShowReque [안드로이드&코틀린] 앨범만들기#2, 액티비티 생명주기, Activity LifeCycle, 안드로이드 라이프사이..

devforyou.tistory.com

intent를 통해서 이미지 파일들을 가져올 수 있도록 한다. 그리고 startActivityForResult를 통해 intent를 열어주고, 그 결과값에 따라 처리할 수 있도록 override 함수를 만들어 준다.

private fun getImageFromAlbum() {
    val intent = Intent(Intent.ACTION_GET_CONTENT)
    intent.type = "image/*"
    startActivityForResult(intent,REQUEST_GET_IMAGE)
}

 

rueqstCode가 올바르게 왔다면, uri를 정상적으로 가져온 것이기 때문에, imageView를 해당 uir로 set해준다. 그러고 나서 전역에 uri값을 등록해주고, 나중에도 이 값을 사용 할 수 있도록 만들어 준다.

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if(resultCode != Activity.RESULT_OK) {
        Toast.makeText(this,"잘못된 접근입니다",Toast.LENGTH_SHORT).show()
        return
    }
    when(requestCode){
        REQUEST_GET_IMAGE -> {
            val selectedImageURI : Uri? = data?.data
            if( selectedImageURI != null ) {
                val imageView = findViewById<ImageView>(R.id.addImageView)
                imageView.setImageURI(selectedImageURI)
                imageURI = selectedImageURI
            }else {
                Toast.makeText(this,"이미지를 가져오지 못했습니다1",Toast.LENGTH_SHORT).show()
            }
        }
        else -> {
            Toast.makeText(this,"이미지를 가져오지 못했습니다2",Toast.LENGTH_SHORT).show()
        }
    }
}

 

# 파이어 베이스에 업로드하기

private fun initSubmitItemButton() {
    submitButton.setOnClickListener {
        val titleEditText = findViewById<EditText>(R.id.addTitleEditText).text.toString()
        val priceEditText = findViewById<EditText>(R.id.addPrcieEditText).text.toString()
        val uid = auth.uid.orEmpty()

        if( titleEditText.isNotEmpty() && priceEditText.isNotEmpty()){
            val articleDB = db.child(DB_ARTICLE)
            val articleModel = ArticleModel(uid,titleEditText,System.currentTimeMillis(),"${priceEditText}원","")
            articleDB.push().setValue(articleModel)
            finish()
        }
    }
}

여러번 했기 때문에 꽤 익숙해 졌다. articleDB.push().setValue(articleModel)는 아직은 로그인 uid값이 없기때문에 push를 통해 임의의 key값을 만들어 주고 그 안에다가 모델을 넣어주도록 한다.

즉 파란색으로 선그어놓은 부분이 push로 생긴 무작위 key값이 된다.

 

# 코드 스타일링

코드에 오타를 줄이고 가독성을 높이기 위해 companion object를 적극 활용한다.

companion object {
    const val REQUEST_FIRST = 1000
    const val REQUEST_GET_IMAGE = 2000
}

또 여러 코틀린 파일에서 쓰일 거 같으면 class로 분리하여 사용한다.

// DBkey.kt
class DBkey {
    companion object {
        const val DB_ARTICLE = "Article"
    }
}

 

# 버그버그

 미리보기에서 설명했듯이 동기처리 방식에 있어서 버그가 발생한다. 파이어베이스에서 값을 가져오는 로직과, 어댑터에 보내줄 list을 clear해주는 과정이 비동기 과정에서 엇갈려 버리기 때문에 발생하는 버그이다. 버그의 원인은 확실히 알 수 있으니, 조금만 시간을 보탠다면 확실히 해결할 수 있을 것 같다.

 

# 마치며

블로그로 정리하는게 시간을 두배 세배로 쓰게 되지만, 이해하는데도 좋고, 나만의 아카이브가 생기는 것 같다는 걸 오늘 조금 느꼈다!

저작자표시 (새창열림)

'•App > 안드로이드 with Kotlin' 카테고리의 다른 글

[에러/안드로이드] 액티비티간 주고받은 uri 권한 연장하기, Permission Denial: opening provider com.android.providers.media.MediaDocumentProvider  (0) 2022.05.25
[안드로이드&코틀린] 앨범 만들기#5, 파이어베이스 스토리지 사용하기, 코틀린 콜백함수, 이미지 업로드하기, 이미지 불러오기, 프로그레스 바, 안드로이드 화면 터치 막기  (0) 2022.05.11
[안드로이드&코틀린] 중고거래앱 만들기#3, 프래그먼트에서 파이어베이스 연결하기, 파이어베이스 동기처리  (1) 2022.05.09
[안드로이드&코틀린] 중고거래앱 만들기#2, 중고 물품 정보 리사이클러 뷰 만들기, 프래그먼트에 리사이클러뷰 추가하기, 홈 화면 구성하기, 뷰바인딩  (7) 2022.05.09
[안드로이드&코틀린] 중고거래앱 만들기#1, 프래그먼트 이용하여 하단메뉴바 만들기, setOnItemSelectedListener, supportFragmentManager, BottomNavigationView  (1) 2022.05.08
    '•App/안드로이드 with Kotlin' 카테고리의 다른 글
    • [에러/안드로이드] 액티비티간 주고받은 uri 권한 연장하기, Permission Denial: opening provider com.android.providers.media.MediaDocumentProvider
    • [안드로이드&코틀린] 앨범 만들기#5, 파이어베이스 스토리지 사용하기, 코틀린 콜백함수, 이미지 업로드하기, 이미지 불러오기, 프로그레스 바, 안드로이드 화면 터치 막기
    • [안드로이드&코틀린] 중고거래앱 만들기#3, 프래그먼트에서 파이어베이스 연결하기, 파이어베이스 동기처리
    • [안드로이드&코틀린] 중고거래앱 만들기#2, 중고 물품 정보 리사이클러 뷰 만들기, 프래그먼트에 리사이클러뷰 추가하기, 홈 화면 구성하기, 뷰바인딩
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바