[Android TIL] 240404 (ํŒ€ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„ ์™„๋ฃŒ, ๊ฐ์ข… ์ด์Šˆ ์ž‘์„ฑ ๋ฐ ํ•ด๊ฒฐ, ppt ์ž‘์„ฑ)
๋ฐ˜์‘ํ˜•

 

 

 

 

 

๐ŸŒฑ Today I Learned (์ง‘์ค‘ ์‹œ๊ฐ„: 12์‹œ๊ฐ„ 55๋ถ„)

  1. (10:00 ~ 11:00 / 1์‹œ๊ฐ„) ํŒ€ํ”„๋กœ์ ํŠธ ํšŒ์˜
  2. (11:00 ~ 12:50 / 1์‹œ๊ฐ„ 50๋ถ„) ์Šคํƒ ๋‹ค๋“œ๋ฐ˜ 3์ฃผ์ฐจ ๊ฐ•์˜ : Fragment, Recycler View, ๋ผ์ด๋ธŒ ์ฝ”๋”ฉ
  3. (14:00 ~ 18:20 / 4์‹œ๊ฐ„ 20๋ถ„) ํŒ€ํ”„๋กœ์ ํŠธ ํšŒ์˜ ๋ฐ Git Issue ์ฐจ๋ก€๋กœ ๊ตฌํ˜„
  4. (19:30 ~ 22:00 / 2์‹œ๊ฐ„ 30๋ถ„) ํŒ€ํ”„๋กœ์ ํŠธ ํšŒ์˜ ๋ฐ develop์— ์ „๋ถ€ ํ•ฉ์นจ, ๊ฐ์ž ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… PPT์ž‘์„ฑ
  5. (12:30 ~ 01:30 / 1์‹œ๊ฐ„) TIL ์ž‘์„ฑ ๋ฐ ์ •๋ฆฌ
  6. (01:30 ~ 01:40 / 10๋ถ„) ์ž‘์„ฑํ•œ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ppt์— ๋ฌธ์ œ ์ƒํ™ฉ gif ์ฒจ๋ถ€
  7. (01:40 ~ 02:15 / 35๋ถ„) ๋งˆ์ง€๋ง‰ ์„ ํƒ๋ถ€๋ถ„ ๊ตฌํ˜„ ์™„๋ฃŒ ๋ฐ ๋งˆ์ง€๋ง‰ PR ์š”์ฒญ์™„๋ฃŒ
  8. (02:15 ~ 03:45 / 1์‹œ๊ฐ„ 30๋ถ„) OOO ์ œ์ถœ

*** ์ ์‹ฌ 13:00 ~ 14:00 / ์ €๋… 18:00 ~ 19:00 ์ œ์™ธ

โ€‹

 

 

 

 

1. ์Šคํƒ ๋‹ค๋“œ๋ฐ˜ 3์ฃผ์ฐจ ๊ฐ•์˜ (Fragment, Recycler View, ๋ผ์ด๋ธŒ ์ฝ”๋”ฉ)

 

  • ๋‚จ์˜ ์ฝ”๋“œ๋ฅผ ๊นƒํ—ˆ๋ธŒ์—์„œ ์ž์ฃผ ์ฝ์–ด๋ณด๊ณ  ๋ถ„์„ํ•˜๋Š”๊ฒŒ ์„ฑ์žฅ์— ๋งŽ์€ ๋„์›€์ด ๋จ
  • jetpack bottom navigation, viewpager2๋Š” fragment๊ฐ€ ์ž˜ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Œ

 

๐Ÿ’ก Fragment ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๋ฐฉ์‹ (Bundle, Fragment Result API ๋“ฑ...)

  • 1) ๋ฒˆ๋“ค ์‚ฌ์šฉ ๊ฒฝ์šฐ
    - Bundle๋กœ ์˜ค๋ธŒ์ ํŠธ ๋‹จ์œ„๋กœ ํ‚ค๊ณผ ๊ฐ’์„ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์Œ
    - ๋ฒˆ๋“ค์—์„œ๋Š” ์ง๋ ฌํ™”๋ณด๋‹ค ์„ฑ๋Šฅ์ด ์—ด ๋ฐฐ ์ข‹์€ parcelable ์‚ฌ์šฉ
  • 2) Fragment Result Api ์‚ฌ์šฉ
    - setFragmentResult ๋“ฑ
  • ์ด์™ธ์˜ ๋ฐฉ๋ฒ•์€ ๋‚˜์ค‘์— ์„ค๋ช…ํ•ด์ฃผ์‹ ๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
  • ์ด์ „์— ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ•ด๋‘์—ˆ๋˜ ๋‚ด์šฉ์ด๊ธด ํ•˜๋‹ค.

 

๐Ÿ’ก Recycler View

  • ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๋Š” ๋ถ€๋ถ„๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ฆผ
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•
    1) LinearLayoutManager ์ง€์ • (์—ด 2๊ฐœ ์ด์ƒ์€ GirdLayoutManager,๋ถˆ๊ทœ์น™ํ•œ ๋ชจ์–‘์€ StaggeredGridLayoutManager)
    2) ๋ทฐ ํ™€๋” ํด๋ž˜์Šค ํ™•์žฅ
    3) ๋ทฐํ™€๋”์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ 
  • ViewHolderClassํ™•์žฅ : ๋ฐ˜๋“œ์‹œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    -onCreateViewHolder()
    -onBindViewHolder()
    -getItemCount
  • viewBinding(module-level build.gradle) ์‚ฌ์šฉ
    kotlin extension

 

๋ผ์ด๋ธŒ์ฝ”๋”ฉ

  • ๋ผ์ด๋ธŒ ์ฝ”๋”ฉ์€ ๋‹ค์‹œ ๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค!

 

 

 

 

2. ํŒ€ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„

 

  • ์ด์ œ ์ •๋ง ๋ช‡ ์•ˆ ๋˜๋Š” ๋‚จ์€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ , PR๋กœ ๋ชจ๋‘ ์—ฐ๊ฒฐ ์ง“๊ณ  ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„๋งŒ ๋‚จ์•˜๋‹ค.
  • ์ง€๊ธˆ๊นŒ์ง€์˜ ํšŒ๊ณ ์™€ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…์„ PPT ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ์‹œ๊ฐ„๋„ ๊ฐ€์กŒ๋‹ค.
  • ์˜ค๋Š˜ ๋งˆ์ด ํŽ˜์ด์ง€ ๋ฐ ํ”„๋กœ์ ํŠธ์™€ ๊ด€๋ จํ•ด์„œ ๊ตฌํ˜„ํ•œ ๊ฒƒ๊ณผ ํŠธ๋Ÿฌ๋ธ” ์ด์Šˆ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

 

 

๐Ÿ’ป ๊ตฌํ˜„1. strings.xml (kor) ์„ค์ •

  • new - value resource file - file name์— strings.xml ์„ค์ • - Locale ํด๋ฆญ ํ›„ >> ํด๋ฆญ - Language ์„ค์ •
  • string์—์„œ <string name="์„ค์ •ํ•  ์ŠคํŠธ๋ง ์ด๋ฆ„">์ž์œ ๋กญ๊ฒŒ ์ž…๋ ฅํ•  ์ŠคํŠธ๋ง ๊ฐ’</string> ํ˜•ํƒœ๋กœ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ์ŠคํŠธ๋ง ๋„ค์ž„ ์ปจ๋ฒค์…˜ (ํƒ€์ž…_์•กํ‹ฐ๋น„ํ‹ฐ๋ช…_์ง€์ •ํ• ์ด๋ฆ„)
    <string name="tv_signup_welcome">Sign up to see photos and videos</string>
  • ํ•ด๋‹น ๋‚ด์šฉ์„ ์ž…๋ ฅํ•˜๊ณ  Translations Editor๋ฅผ ์ผœ๋ฉด ์•Œ๋งž์€ ๋ฒˆ์—ญ ๊ฐ’์„ ํŽธํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 

๐Ÿ’ป ๊ตฌํ˜„2. ์ด๋ฏธ์ง€ ํœด๋Œ€ํฐ์—์„œ ์„ ํƒ ํ›„ ๋„˜๊ธฐ๋Š” ๋กœ์ง ๊ตฌํ˜„

// 1. Myactivity ํด๋ž˜์Šค์— profileUri ์ž„์˜๋กœ null ์„ค์ •ํ•ด์„œ ์ „์—ญ๋ณ€์ˆ˜ ์„ค์ •ํ•ด๋†“๊ธฐ
private var profileUri: Uri? = null 

// 2. uri?.let ์•ˆ์— profileUri = it์œผ๋กœ ์„ค์ •
    fun changeProfilePhoto(view: View) {
        pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
    }

    private val pickMedia =
        registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
            uri?.let {
                binding.imgProfile.setImageURI(it)
                profileUri = it
            }
        }
        
// 3. done ํด๋ฆญํ–ˆ์„ ๋•Œ ๊ตฌ๋™๋˜๋Š” editUserInfo(),  image = Image.ImageUri(profileUri!!)

private fun editUserInfo(
        newName: String,
        newBio: String,
        newEmail: String,
        newPhoneNumber: String,
    ) {
        this.grantUriPermission(
            this.packageName, profileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
        )

        with(user) {
            name = newName
            bio = newBio
            email = newEmail
            phoneNumber = newPhoneNumber
            if(profileUri != null){
                image = Image.ImageUri(profileUri!!)
            }

            MemoryStorage.setUser(user)
        }
    }
  • Photo Picker๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ํ•˜๊ณ  ์ˆ˜์ •ํ–ˆ๋‹ค. (๋‹จ์ผํด๋ž˜์Šค์ด๋ฏ€๋กœ Pick Visual Media๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„)
  • ํ•ด๋‹น ๋ถ€๋ถ„์— ์žˆ์–ด ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค๋„ ์ˆ˜์ •ํ•˜๊ณ  ์ •๋ง ์–ด์ฐŒ์ €์ฐŒ ํŒ€์›๋ถ„๋“ค๊ณผ ํŠœํ„ฐ๋‹˜๊ณผ ์ž˜ ํ•ด๊ฒฐ์„ ํ–ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ User์˜ Image ์†์„ฑ์ด val๋กœ ๋˜์–ด์žˆ์–ด์„œ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์–ด var๋กœ ์ˆ˜์ •ํ•˜์˜€๊ณ , ํŒ€์›๋ถ„์˜ ์ฝ”๋“œ๋„ ์•Œ๋งž๊ฒŒ ์ˆ˜์ •๋˜์—ˆ๋‹ค.
  • ์ฐธ๊ณ  ๋ธ”๋กœ๊ทธ: https://mundroid.tistory.com/2 
 

์‚ฌ์ง„ ์„ ํƒ ๋„๊ตฌ  |  Android Developers

DataStore offers a more modern way of storing local data. You should use DataStore instead of SharedPreferences. Read the DataStore guide for more information. ์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ง„ ์„ ํƒ ๋„๊ตฌ ์ปฌ

developer.android.com

 

 

 

 

๐Ÿ’ป ๊ตฌํ˜„3. ์ฒ˜์Œ์— ๊ธฐ์กด user์— ์ €์žฅ๋œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ถœ๋ ฅ

    private fun initUserProfileImage() {
        val image = user.image

        binding.run {
            when(image) {
                is Image.ImageDrawable -> civProfileImage.setImageResource(image.drawable)
                is Image.ImageUri -> civProfileImage.setImageURI(image.uri)
            }
        }
    }
  • ์ด๋ฏธ์ง€๊ฐ€ ๋ฐ”๋€ ๋’ค ๋ฐ˜์˜๋˜๋Š” ๊ฑด ๊ตฌํ˜„ํ•ด๋†จ๋Š”๋ฐ, ์ฒ˜์Œ์— ๋“ค์–ด์™”์„ ๋•Œ user์— ์ €์žฅ๋œ ์ด๋ฏธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜์ง€ ๋ชปํ–ˆ์—ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” initUserProfileImage()๋ฅผ ๊ฐ€์ ธ์™”๋‹ค.
  • image๊ฐ€ Image.Imagedrawable ํƒ€์ž…์ผ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ’์— ๋งž๊ฒŒ ์„ค์ •ํ•˜๊ณ , Uri์˜ ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค.
    ๋‹ค๋งŒ ์ด ๋กœ์ง์„ ๋‚˜์ค‘์— ๋” ์ƒ๊ฐํ•ด๋ด์•ผ ๊ฒ ๋‹ค. is์˜ ๊ฒฝ์šฐ ์Šค๋งˆํŠธ ์บ์ŠคํŒ…: ํƒ€์ž… ๊ฒ€์‚ฌ ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ ๊ถ๊ธˆํ–ˆ๋‹ค.
  • run๊ณผ when์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ๊ฐ„๊ฒฐํ•ด์กŒ๋‹ค. 

 

 

 

๐Ÿ’ป ๊ตฌํ˜„4. Edittext์—์„œ ์—”ํ„ฐ๋ฅผ ์น˜๋ฉด ์•„๋ž˜ Edittext๋กœ ์˜ฎ๊ฒจ๊ฐ€๊ธฐ

android:singleLine="true"
  • XML์—์„œ ์ด ํ•œ ์ค„๋งŒ ์ถ”๊ฐ€ํ•ด๋„ ์—”ํ„ฐ ๋ˆ„๋ฅด๋ฉด ๋‹ค์Œ์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. ์‹ฑ๊ธ€๋ผ์ธ์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ์˜คํ† ํฌ์ปค์‹ฑ์— ๊ด€ํ•œ ๋‚ด์šฉ์„ ์–ด์ œ ์ž‘์„ฑํ–ˆ์—ˆ๋Š”๋ฐ, ๊ทธ๊ฒƒ๋ณด๋‹ค ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.
  • ํฌ์ปค์Šค์™€์˜ ์ฐจ์ด์ ์€, ํฌ์ปค์Šค๋กœ ํ•˜๋ฉด ์—”ํ„ฐ ๋ฒ„ํŠผ ๋Œ€์‹  ๋ฐ‘์œผ๋กœ ๋‚ด๋ ค๊ฐ„๋‹ค๋Š” ํ™”์‚ด์ด ์ถœ๋ ฅ๋œ๋‹ค.

 

 

 

๐Ÿ”จ ์ด์Šˆ1. Pull Request์— ๊ฐ commit์ด ์ค„์ค„์ด ๋‹ฌ๋ฆฌ๋Š” ๋ฌธ์ œ

  • ์šฐ๋ฆฌ ํŒ€์—์„œ PR์„ ํ–ˆ์„ ๋•Œ, ๋‹ค๋“ค ์ปค๋ฐ‹์ด ๊ณ„์† ์ถ”๊ฐ€๋˜๋ฉฐ PR์— ์ปค๋ฐ‹์ด ์ฃผ๋ ์ฃผ๋  ๋‹ฌ๋ ค์žˆ์—ˆ๋‹ค.
  • ์ด์œ ์ธ ์ฆ‰์Šจ, ๋ณดํ†ต์€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์œ„์ฃผ๋กœ branch๋ฅผ ์ƒ์„ฑํ•˜๊ณ  develop์— ๋ฐ˜์˜ํ•˜๊ณ  ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ํ˜•์‹์„ ๋ฐ˜๋ณตํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ์•กํ‹ฐ๋น„ํ‹ฐ๋ผ๋Š” ํฐ ๋‹จ์œ„ ๊ธฐ์ค€์œผ๋กœ branch๋ฅผ ๋‚˜๋ˆ ์„œ ์ค„์ค„์ด ์ปค๋ฐ‹ ์†Œ์‹œ์ง€๊ฐ€ ๋‹ฌ๋ฆฐ ๊ฑฐ์˜€๋‹ค.
  • ๋ธŒ๋žœ์น˜ ์ „๋žต์— ๋Œ€ํ•ด์„œ ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ PR์—์„œ ํƒœ๊ทธ๋ฅผ ๋‹ฌ๋ฉด ํ›จ์”ฌ ๊น”๋”ํ•˜๋‹ค๋Š” ์ ๋„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.

๋ธŒ๋žœ์น˜ ์ „๋žต

 

 

 

๐Ÿ”จ ์ด์Šˆ2. ์ฝœ๋ฐฑ๋ฉ”์„œ๋“œ ์‹œ์  ์ƒ๊ฐํ•˜๊ธฐ, ์ƒ์• ์ฃผ๊ธฐ ๊ณ ๋ฏผํ•˜๊ธฐ

// onResume() ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ
        override fun onResume() {
        super.onResume()
        when (user.image) {
            is Image.ImageDrawable -> {
                val drawable = user.image as Image.ImageDrawable
                binding.civProfileImage.setImageResource(drawable.drawable) //
            }
            is Image.ImageUri -> {
                val uri = (user.image as Image.ImageUri).uri
                binding.civProfileImage.setImageURI(uri)
            }
        }
    }
  • ์œ ์ €์˜ ์ด๋ฏธ์ง€๊ฐ’์„ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋กœ์ง์— ๋Œ€ํ•ด ์งˆ๋ฌธํ–ˆ์„ ๋•Œ, ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ ์‹œ์ ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด๋ณด๋Š” ๊ฒŒ ์ข‹๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ์ •์˜๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    1) ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ์จ ์ด์šฉ๋˜๋Š” ํ•จ์ˆ˜
    2) ์–ด๋–ค ์ด๋ฒคํŠธ์— ์˜ํ•ด ํ˜ธ์ถœ๋˜์–ด์ง€๋Š” ํ•จ์ˆ˜
  • myactivity์—์„œ mainactivity๋กœ ๊ฐ’์„ ๋ณด๋‚ด๊ณ , mainactivity์—์„œ myactivity๋กœ ๊ฐ’์„ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์ƒ๋ช…์ฃผ๊ธฐ์— ๋”ฐ๋ฅธ ์ฝ”๋“œ ์œ„์น˜๋‚˜ onResume()์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์ด ์กฐ๊ธˆ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  User ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค ์† Image๋ฅผ ์‹ค๋“œ ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์— ๋Œ€ํ•ด์„œ ํŠœํ„ฐ๋‹˜์ด ์˜๋ฌธ์„ ํ’ˆ์œผ์…จ๋‹ค.
    ์‹ค๋“œ ๋ง๊ณ  ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•˜์‹œ๋ฉด์„œ, '๋ฐ์ดํ„ฐ ํด๋ž˜์Šค์˜€์œผ๋ฉด .์„ ์ด์šฉํ•ด์„œ ๋ฐ”๋กœ ๋ฐ”๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ• ํ…๋ฐ ๊ทธ๊ฒŒ ์•ˆ๋ผ์„œ ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ์ˆ˜์ •ํ•˜๊ณ  ์ ‘๊ทผ์ด ํž˜๋“ ๊ฑฐ๋‹ค' ๋ผ๋Š” ์–˜๊ธฐ๋ฅผ ํ•ด์ฃผ์…จ๋‹ค.
  • ํ•ด๋‹น ๋ถ€๋ถ„์€ ํŒ€์›๋“ค๊ณผ ๋…ผ์˜ํ•œ ๊ฒฐ๊ณผ, ์ผ๋‹จ ์ดˆ๊ธฐ ๊ตฌํ˜„์˜ ๋ฌธ์ œ๋กœ ์‹ค๋“œ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋ผ์„œ ํ•ด๋‹น ํด๋ž˜์Šค์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ •๋ฆฌ๋๋‹ค. ๋‚˜์ค‘์— ์ •๋ง ์ฝ”๋“œ๋ฅผ ์ž˜ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋์„ ๋•Œ ๋‹ค์‹œ ์ฝ”๋“œ๋ฅผ ๋œฏ์–ด๋ณด๊ณ  ์‹ถ๋‹ค.

 

 

 

๐Ÿ”จ ์ด์Šˆ3. ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  Done๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์•ฑ์ด ๋‹ค์šด๋˜๋Š” ๋ฌธ์ œ

 

  • ๋งˆ์ดํŽ˜์ด์ง€์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์€ ์ฑ„ ๋‹ค๋ฅธ ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ๋‹ค.
  • ์›์ธ์€ ํ”„๋กœํ•„์„ ์ˆ˜์ •ํ•˜๋Š” ํ•จ์ˆ˜ editUserInfo ์—์„œ user์˜ ์ด๋ฏธ์ง€๊ฐ’์— profileUri!! ๋ฅผ ์ง€์ •ํ•œ ์ฝ”๋“œ๋‹ค.
    ์ด๋ฏธ์ง€๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” profileUri๊ฐ€ Null์ผํ…๋ฐ, !!(Not Null)๋กœ ๊ฐ’์„ ๋ฐ›์•„์ฃผ๋Š” ๋ฐ”๋žŒ์— ์•ฑ์ด ๋‹ค์šด๋˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ If๋ฌธ์œผ๋กœ null์ด ์•„๋‹ ๋•Œ๋งŒ ๋ฐ›๋„๋ก ์กฐ๊ฑด์„ ์„ค์ •ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค.

 

 

 

 

๐Ÿ”จ์ด์Šˆ4. ์‚ฌ์ง„์„ ์ˆ˜์ • ํ›„ ๋‹ค์‹œ ํŽธ์ง‘ ํŽ˜์ด์ง€๋ฅผ ๋“ค์–ด๊ฐ€๋ฉด ์•ฑ์ด Down๋จ

 

 

  • ๊ถŒํ•œ ๋ถ€์—ฌ์˜ ๋ฌธ์ œ์˜€๋‹ค.
  • Intent.FLAG_GRANT_READ_URI_PERMISSION์€ ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ”Œ๋ž˜๊ทธ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.
  • ์ด ํ”Œ๋ž˜๊ทธ๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๋‚˜ ์„œ๋น„์Šค๊ฐ€ ํŠน์ • URI(Uniform Resource Identifier)์— ๋Œ€ํ•œ ์ฝ๊ธฐ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค๋ฅธ ์•ฑ์ด๋‚˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ, ์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ๋ฐ์ดํ„ฐ ๋…ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ ์šฉํ•œ๋‹ค. ์ด๋•Œ FLAG_GRANT_READ_URI_PERMISSION์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์†Œ์œ ํ•œ ์•ฑ์ด ๋‹ค๋ฅธ ์•ฑ์—๊ฒŒ ํ•ด๋‹น ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค.. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ ์•ฑ์—๊ฒŒ ๊ฐค๋Ÿฌ๋ฆฌ์— ์žˆ๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ œ๊ณตํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•ด๋‹น ์ด๋ฏธ์ง€์— ๋Œ€ํ•œ URI๋ฅผ ํฌํ•จํ•œ ์ธํ…ํŠธ์— FLAG_GRANT_READ_URI_PERMISSION ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ, ๋Œ€์ƒ ์•ฑ์ด ์ด ์ด๋ฏธ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ณด์•ˆ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ถŒํ•œ ๋ถ€์—ฌ ์—†์ด๋Š” ๋‹ค๋ฅธ ์•กํ‹ฐ๋น„ํ‹ฐ ๊ฐ„์˜ ์ด๋ฏธ์ง€ ์ „๋‹ฌ์ด ์•ˆ ๋˜๋Š” ๊ฒƒ ๊ฐ™์•˜๋‹ค.
    ์ด ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ํŒ€์› ๋ถ„๋“ค๊ณผ ์ธํ„ฐ๋„ท์„ ์„œ์นญํ•ด๋„ '๋ณด์•ˆ' ๊ด€๋ จ ์ด์•ผ๊ธฐ ์™ธ์—” ๋‹ค๋ฅธ ํ•ด๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
  • ์ฐธ๊ณ ๋กœ ์ € ์ฝ”๋“œ์˜ ์œ„์น˜ ๋˜ํ•œ ์ค‘์š”ํ–ˆ๋Š”๋ฐ, ์ €๊ฒƒ์ฒ˜๋Ÿผ imageUri๋ฅผ ์„ค์ •ํ•ด ์ฃผ๊ธฐ์ „์— ๊ถŒํ•œ์„ ๋จผ์ € ํ• ๋‹นํ•ด์ค˜์•ผ ํ–ˆ๋‹ค.

 

 

Notification ๋ฌธ์ œ | ์ฐฐ์Šค์˜ ์•ˆ๋“œ๋กœ์ด๋“œ

Head-up notification Android 5.0(API ๋ ˆ๋ฒจ 21)์—์„œ๋Š” ์•Œ๋ฆผ์„ ์ž‘์€ ๋ถ€๋™ ์ฐฝ์— ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (๋‹ค๋ฅธ ๋ง๋กœ ํ—ค๋“œ์—… ์•Œ๋ฆผ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค). ์ด๊ฒƒ์€ ๊ธฐ๊ธฐ๊ฐ€ ํ™œ์„ฑ ์ƒํƒœ์ผ ๋•Œ(์ฆ‰, ๊ธฐ๊ธฐ๊ฐ€ ์ž ๊ธˆ ํ•ด์ œ ์ƒํƒœ์ด๋ฉฐ

www.charlezz.com

 

์ฝ˜ํ…์ธ  ๋ฆฌ์กธ๋ฒ„  |  App quality  |  Android Developers

์ฝ˜ํ…์ธ  ๋ฆฌ์กธ๋ฒ„ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. OWASP ์นดํ…Œ๊ณ ๋ฆฌ: MASVS-PLATFORM: ํ”Œ๋žซํผ ์ƒํ˜ธ์ž‘์šฉ ๊ฐœ์š” ์ด ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ContentResolver๋Š” '์• ํ”Œ๋ฆฌ์ผ€

developer.android.com

 

 

 

 

๐Ÿ”จ์ด์Šˆ5. ๋งˆ์ดํŽ˜์ด์ง€ -> ๋กœ๊ทธ์ธํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ ๋’ค๋กœ๊ฐ€๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ์•ฑ ์ข…๋ฃŒ์‹œํ‚ค๊ธฐ

  • ๋งˆ์ดํŽ˜์ด์ง€์— ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๊ฐ€๋Š” ๋ฒ„ํŠผ(์–ด์ฐŒ๋ณด๋ฉด ๋กœ๊ทธ์•„์›ƒ๊ณผ ๋น„์Šท)์ด ๊ตฌํ˜„๋˜์–ด์žˆ๋Š”๋ฐ, ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ ํ›„ ๋’ค๋กœ๊ฐ€๊ธฐ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ ๋‹ค์‹œ ์ด์ „ํŽ˜์ด์ง€์ธ ๋งˆ์ดํŽ˜์ด์ง€๊ฐ€ ํ˜ธ์ถœ ๋๋‹ค.
  • ์ด์— ๋Œ€ํ•ด์„œ ๋ฒ„ํŠผ์„ ํ†ตํ•ด ๋„˜๊ธฐ๋Š” ์ธํ…ํŠธ ์ชฝ์— ์ธํ…ํŠธ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ด์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ ๋๋‹ค.
  • switchIntent.flags =Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
    ์ง€๊ธˆ๊นŒ์ง€ ์Œ“์—ฌ์žˆ๋˜ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•˜๊ณ  ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ

 

 

 

๊ธฐํƒ€ ์ •๋ฆฌํ•˜์ง€ ๋ชปํ•œ ์ด์Šˆ๋‚˜ ์ƒํ™ฉ์œผ๋กœ๋Š”

1) deprecated๋œ ์• ๋‹ˆ๋ฉ”์ด์…˜(overridePendingTransition())๊ณผ ๊ทธ ์ด์œ  ์ฐพ๊ธฐ
2) PPT ์ž‘์„ฑ

์ •๋„๊ฐ€ ์žˆ๋‹ค. ํ•˜๋ฃจ์— ๊ฒช์€ ๋ฌธ์ œ ๋ฐ ํ•ด๊ฒฐ๋“ค์ด ๊ณ„์† ๋งŽ๋‹ค๋ณด๋‹ˆ TIL์„ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์ด ๋งค์šฐ ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค.

 

 

๐Ÿ’ญ Retrospect

์ด๋ฒˆ ์ฃผ ๋‚ด๋‚ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ชป ํ’€๊ณ  ์žˆ๋‹ค. ์ž…๋ฌธ ๊ต์œก ์ฃผ์ฐจ๊นŒ์ง€๋Š” ์ž์œ  ์‹œ๊ฐ„์ด ๋„๋„ํ–ˆ์Œ ๋„๋„ํ–ˆ์ง€, ์ด๋ ‡๊ฒŒ๊นŒ์ง€ ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•ด์งˆ์ค„์€ 1๋„ ๋ชฐ๋ž๋‹ค. ์ด๋ฒˆ ์ฃผ๋Š” ๋งค์ผ ํ•ด์•ผ ํ•  ํˆฌ๋‘๋ฆฌ์ŠคํŠธ๋“ค์ด ๋‹น์ผ์— ํ•ด๊ฒฐ์ด ์•ˆ ๋˜๊ณ  ๋‹ค์Œ๋‚  ์‹ฌ์ง€์–ด๋Š” ๋‹ค๋‹ค์Œ๋‚ ๊นŒ์ง€ ์Šคํƒ๋˜์–ด๊ฐ€๋”๋ผ. ๋  ์ˆ˜ ์žˆ์œผ๋ฉด ์ด๋ฒˆ ์ฃผ๋ง๊ณผ, ์ˆ™๋ จ ๊ต์œก ์ฃผ์ฐจ์ธ ๋‹ค์Œ์ฃผ์— ๋ฐ€๋ฆฐ ์ผ๋“ค์„ ์‹ธ๊ทธ๋ฆฌ ํ•ด์น˜์šฐ๋Š” ๊ฒŒ ๋ชฉํ‘œ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ดˆ๋ฐ˜์—๋Š” ํŒ€์› ๊ฐœ๊ฐœ์ธ๋งˆ๋‹ค ๊ฐ€์ง„ ์—ญ๋Ÿ‰๊ณผ ๊ฒฝํ—˜์น˜๋„ ๋‹ค๋ฅด๊ณ , ํ˜‘์—…์œผ๋กœ ์œ ๋ฐœ๋˜๋Š” Git ์˜ค๋ฅ˜๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•ด๋ณด์ง€ ๋ชปํ–ˆ๋˜ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ์—ฌ๋Ÿฌ๋ชจ๋กœ ํž˜๋“ค์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ›„๋ฐ˜์— ์ ‘์–ด๋“  ์ง€๊ธˆ์€ ๊ทธ๋ƒฅ ๋ญ๋ž„๊นŒ ๋งŽ์ด ํ›„๋ จํ•˜๊ธฐ๋„ ํ•˜๊ณ  ์—„์ฒญ ๋ฐœ์ „ํ•œ ๊ฒƒ ๊ฐ™๋‹ค. Git์„ ํ˜ผ์ž ์‚ฌ์šฉํ–ˆ์œผ๋ฉด ์ „ํ˜€ ๊ฒช์–ด๋ณด์ง€ ๋ชปํ–ˆ์„ ๊ฒฝํ—˜๋„ ๋งŽ์ด ํ–ˆ๊ณ , ๋‹ค๋ฅธ ํŒ€์›๋ถ„๋“ค์˜ ์ฝ”๋“œ ๊ตฌํ˜„์„ ๋ณด๋ฉด์„œ '์ด๊ฑด ๋ฌด์Šจ ์ฝ”๋“œ์ง€?' '์™œ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ–ˆ์ง€?'ํ•˜๋Š” ์ƒ๊ฐ์„ ๊ฑฐ์น˜๋ฉด์„œ๋„ ์„ฑ์žฅํ–ˆ๋‹ค. ๋ฐฐ์šธ ์ ์ด ๋งŽ์€ ๋ถ„๋“ค๊ณผ ํŒ€์ด ๋˜์–ด์„œ ์ข‹์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค.
์บ ํ”„๊ฐ€ ์ง„ํ–‰๋ ์ˆ˜๋ก ์‚ฌ๋žŒ๋“ค๋ผ๋ฆฌ ์นœํ•ด์ง€๋Š” ๊ฒŒ ์‹ ๊ธฐํ•˜๋‹ค. 

โ€‹

 

 

 

 

 

๋ฐ˜์‘ํ˜•
 ๐Ÿ’ฌ C O M M E N T