๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค2024 ์•ˆ๋“œ๋กœ์ด๋“œ/โ˜€๏ธ ํ•˜๊ณ„ ์ธํ„ด ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก

Android ๊ถŒํ•œ ์š”์ฒญ ์ฒ˜๋ฆฌํ•˜๊ธฐ (๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ??)

by hyeonha 2024. 8. 23.

๋ชฉ์ฐจ

    ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—

    ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ์‚ฌ์šฉ์ž์˜ ์œ„์น˜๋ฅผ ์ธก์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์—์„œ๋Š” ์œ„์น˜ ๊ถŒํ•œ ์š”์ฒญ์ด๋ผ๋Š” ๊ถŒํ•œ์ด ํ•„์š”ํ–ˆ๋‹ค. 

    ์ฒ˜์Œ์—๋Š” ๊ถŒํ•œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋Œ€์ˆ˜๋กญ์ง€ ์•Š๊ฒŒ ์—ฌ๊ฒผ๋Š”๋ฐ, ๊ถŒํ•œ์„ ์ œ๋Œ€๋กœ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋Šฅ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜๋‹ค. 

     

    ์œ„์น˜๊ฐ€ ์ œ๋Œ€๋กœ ๋ฐ›์•„์™€์ง€์ง€ ์•Š์•„์„œ ๊ณจ์น˜๊ฐ€ ์•„ํŒ ๋Š”๋ฐ ๊ฒฐ๊ตญ ๋‚˜์ค‘์— ๋ณด๋‹ˆ ๊ถŒํ•œ ์ด๋…€์„์ด ๋ฌธ์ œ์˜€๋‹ค!!!!

    ์ฒ˜์Œ์—๋Š” ์„ค๋งˆ ๊ถŒํ•œ ๋ฌธ์ œ์ผ๊นŒ ์ƒ๊ฐ์น˜ ๋ชปํ•ด์„œ ์—„์ฒญ ํ—ค๋งธ๋‹ค ใ… ใ… 

     

    ์•ž์œผ๋กœ๋„ ํ•„์ˆ˜์ ์œผ๋กœ ์•Œ์•„์•ผํ•  ์‚ฌํ•ญ์ด๋‹ˆ ์ œ๋Œ€๋กœ ์ •๋ฆฌํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค!!!

    ๊ถŒํ•œ์ด๋ž€?

    ๋จผ์ € ๊ถŒํ•œ์ด ๋ฌด์—‡์„ ๋งํ•˜๋Š” ๊ฑธ๊นŒ?

    ์•ฑ์„ ์„ค์น˜ํ•ด์„œ ๋“ค์–ด๊ฐ€๋ คํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ฐฝ์ด ๋œจ๋ฉด์„œ ~ํ—ˆ์šฉํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋ผ๋Š” ๋ฉ˜ํŠธ๋ฅผ ์ž์ฃผ ๋ณธ ๊ธฐ์–ต์ด ์žˆ์„ํ…๋ฐ ๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ ํ—ˆ์šฉ/๊ฑฐ๋ถ€์— ๋Œ€ํ•ด ๋ฌป๋Š” ๊ฒƒ์ด ์˜ค๋Š˜ ๋‹ค๋ฃฐ ๊ถŒํ•œ์ด๋‹ค!

    ์ •ํ™•ํžˆ ๋งํ•˜์ž๋ฉด ๊ถŒํ•œ์€ ์‚ฌ์šฉ์ž์˜ ๋ฏผ๊ฐํ•œ ์ •๋ณด์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•˜๊ณ  ์•ฑ์ด ์–ด๋–ค ์ •๋ณด์— ์ ‘๊ทผํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์–ด ์ธ์ง€๋„๋ฅผ ๋†’์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

    ๋ฒ„์ „ ๋ณ„๋กœ ํ•„์š”ํ•œ ๊ถŒํ•œ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

    ๊ถŒํ•œ์˜ ์ข…๋ฅ˜

    ๊ถŒํ•œ์€ 2๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰œ๋‹ค.

    1. Install-time 

    ์•ฑ์„ ์„ค์น˜ํ•  ๋•Œ  ์ž๋™์œผ๋กœ ๋ถ€์—ฌ๋˜๋Š” ๊ถŒํ•œ์ด๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณ„๋„์˜ ํ—ˆ๊ฐ€๋ฅผ ์š”์ฒญํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ธํ„ฐ๋„ท ์ ‘๊ทผ ๊ถŒํ•œ์ด ์—ฌ๊ธฐ์— ํ•ด๋‹นํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ถŒํ•œ์€ ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ์ •๋ณด์— ์ง์ ‘์ ์ธ ์œ„ํ—˜์„ ์ฃผ์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•œ๋‹ค.

     

    2. Runtime

    ์•ฑ์ด ์‹คํ–‰ ์ค‘์ผ ๋•Œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ง์ ‘ ์š”์ฒญํ•ด์•ผํ•˜๋Š” ๊ถŒํ•œ์ด๋‹ค. ์ฃผ๋กœ ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ ์ •๋ณด์™€ ๊ด€๋ จ๋œ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ ํ•„์š”ํ•˜๋‹ค.

     

    ๊ถŒํ•œ ์š”์ฒญ ๊ณผ์ •

    ๊ถŒํ•œ ๊ฒ€์‚ฌํ•˜๊ธฐ

    1. ์šฐ์„  ์ด๋ฏธ ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผํ•œ๋‹ค.

    ์•ฑ์˜ ์ตœ์†Œ ์‹œ์ž‘ ์‹œ์—๋Š” ๋‹น์—ฐํžˆ ๊ถŒํ•œ ์š”์ฒญ์„ ๋ฐ”๋กœ ํ•ด๋„ ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‹ค์Œ๋ถ€ํ„ฐ๋Š” ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ์–ด๋–ป๊ฒŒ ๊ฒ€์‚ฌํ• ๊นŒ?

     

    ์ด ๋•Œ๋Š” ContextCompat.checkSelfPermission(Context, ๊ถŒํ•œ)์„ ํ†ตํ•ด ๊ถŒํ•œ์„ ์ „๋‹ฌํ•˜์—ฌ ๋ฐ˜ํ™˜๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. 

    ์ด ๋ฐ˜ํ™˜๊ฐ’๊ณผ  PackManager.PERMISSION.GRANTED์™€ ๋น„๊ตํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

     

    - ๋งŒ์•ฝ  ๊ถŒํ•œ์ด ์ด๋ฏธ ํ—ˆ์šฉ๋˜์–ด์žˆ๋‹ค๋ฉด ContextCompat.checkSelfPermission(Context, ๊ถŒํ•œ) ๋Š”  PERMISSION.GRANTED๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ  ์กฐ๊ฑด์€ ์ฐธ์ด ๋œ๋‹ค.

    - ๋งŒ์•ฝ ๊ถŒํ•œ์ด ์—†๋‹ค๋ฉด ๊ฑฐ์ง“์ธ ๊ฒฝ์šฐ   ContextCompat.checkSelfPermission(Context, ๊ถŒํ•œ) ๋Š”  PERMISSION_DENIED๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ   ์กฐ๊ฑด์€ ๊ฑฐ์ง“์ด ๋˜๊ณ  , ์ด ๋•Œ ์œ„์น˜ ๊ถŒํ•œ์„ ์š”์ฒญํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

     

    ์•ฑ์—์„œ ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ

    ๋งŒ์•ฝ ์œ„ ๊ณผ์ •์—์„œ ๊ถŒํ•œ์ด ์•„์ง ๋ถ€์—ฌ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด ์‚ฌ์šฉ์ž‘๊ฐ€ ํ•ด๋‹น ๊ถŒํ•œ์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•ด๋‹น ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ด์ฃผ๋ฉด ์ข‹๋‹ค.

     shouldShowRequestPermissionRationale()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ด ์•ฑ์—์„œ ํ•ด๋‹น ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„ค๋ช…ํ•˜๊ฑฐ๋‚˜ ๋ฐ”๋กœ ๊ถŒํ•œ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค

     

    ๊ถŒํ•œ ์š”์ฒญ

    ์„ค๋ช…์„ ํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ๋™์˜ํ•œ ๊ฒฝ์šฐ ๊ถŒํ•œ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์—์„œ ์‚ดํŽด๋ณธ install-in ๊ถŒํ•œ๊ณผ runtime ๊ถŒํ•œ์€ ์š”์ฒญ๋ฐฉ๋ฒ•์ด ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค.

     

    ์šฐ์„  ๊ณตํ†ต์ ์œผ๋กœ ๋‘ ๊ถŒํ•œ ๋ชจ๋‘ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์—์„œ ํ•„์š”ํ•œ permission์„ ๋ช…์‹œํ•ด์ค€๋‹ค. 

     

    ๋‚˜๋Š” ์›น ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธํ„ฐ๋„ท ๊ถŒํ•œ์„ ํ—ˆ์šฉํ•ด์ฃผ์–ด์•ผํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ์— ์ธํ„ฐ๋„ท ๊ถŒํ•œ์„ ํ—ˆ๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

    <uses-permission android:name="android.permission.INTERNET" />

     

    ๋˜ํ•œ ์›Œ์น˜๋ฅผ ์‚ฌ์šฉํ•  ์‚ฌ์šฉ์ž์˜ ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ ์œ„์น˜ ๊ด€๋ จ ๊ถŒํ•œ์ด ํ•„์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—  ์•„๋ž˜์™€ ๊ฐ™์ด ์œ„์น˜ ๊ด€๋ จ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

     

    ์ž ๊ทธ๋Ÿผ ๊ถŒํ•œ ์š”์ฒญ ๋ ~?

     

    install-time ๊ถŒํ•œ์˜ ํ•œ ์ข…๋ฅ˜์˜€๋˜ ์ธํ„ฐ๋„ท ๊ถŒํ•œ ์š”์ฒญ์€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์— ์„ ์–ธํ•ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ๊ถŒํ•œ ์š”์ฒญ์ด ์™„๋ฃŒ๋œ๋‹ค.

    ๊ทธ๋Ÿฌ๋‚˜ runtime ๊ถŒํ•œ์˜ ๊ฒฝ์šฐ ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

     

    ๊ถŒํ•œ ์š”์ฒญ ๋ฐฉ๋ฒ• 

    1. onRequestPermissionResult (deprecated) : ์ฒ˜์Œ์—๋Š” ์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ์ด์ œ deprecated๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

    ๊ทธ๋ž˜๋„ ์•ˆ๋ณด๋ฉด ์•„์‰ฌ์šฐ๋‹ˆ๊นŒ onRequestPermissionResult ๋ฐฉ์‹๋„ ๊ฐ„๋‹จํ•˜๊ฒŒ๋งŒ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

    grantResults๊ฐ’์„ ํ†ตํ•ด ๊ถŒํ•œ์ด ํ—ˆ๊ฐ€๋˜์—ˆ๋Š”์ง€ ๊ฑฐ๋ถ€๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•ด์ฃผ๊ณ  ์ผ€์ด์Šค์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

      override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            if	(grantResults[0] == PackManager.PERMISSION_GRANTED) {
            	// ๊ถŒํ•œ์ด ํ—ˆ๊ฐ€๋œ ๊ฒฝ์šฐ ๋™์ž‘ ์ •์˜
            }
            else {
               // ๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋œ ๊ฒฝ์šฐ ๋™์ž‘ ์ •์˜
            }
        }

     

    ์œ„ ๋ฐฉ์‹์€ deprecated๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ๊ถŒํ•œ์„ ์š”์ฒญํ•ด์•ผํ•˜๋‚˜์š” !!?

     

    2.  registerForActivityResult(ActivityResultContracts.RequestPermission() ) ๋ฅผ ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

     

    1. ์šฐ์„  ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ์š”์ฒญ์ด ํ•„์š”ํ•œ ๊ถŒํ•œ ๋ชฉ๋ก์„ ๋งŒ๋“ค์–ด์ค€๋‹ค.

     private val permissionList = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            )

     

    ๊ทธ๋ฆฌ๊ณ  ๊ถŒํ•œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•ด์ค€๋‹ค.

      private val requestPermissionResult = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) { permission ->
            if (permission.all { it.value }) {
                Log.d("๊ถŒํ•œ ํ—ˆ์šฉ", "${permission} ๊ถŒํ•œ ํ—ˆ์šฉ")
            } else {
                Log.d("๊ถŒํ•œ ๊ฑฐ๋ถ€", "$permission ๊ถŒํ•œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค")
            }
        }

     

    ์ž ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ์•„๋ž˜์˜ ์ฝ”๋“œ ํ•œ์ค„๋งŒ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๊ถŒํ•œ ์š”์ฒญ๊ณผ ์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋œ๋‹ค.

            requestPermissionResult.launch(permissionList)

     

    ์ฝ”๋“œ๋กœ ์•Œ์•„๋ณด๊ธฐ

    1. ๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ๋˜์–ด์žˆ๋Š”์ง€ ์ฒดํฌํ•˜๊ธฐ

    2. ์•„๋‹Œ ๊ฒฝ์šฐ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ์ด์œ  ์„ค๋ช…ํ•˜๊ธฐ 

    3. ๋™์˜ํ•œ ๊ฒฝ์šฐ ์œ„์น˜ ๊ถŒํ•œ ์š”์ฒญํ•˜๊ธฐ

     private fun checkPermission() {
            when {
                permissionList.all { ContextCompat.checkSelfPermission(this,it) == PackageManager.PERMISSION_GRANTED }
                -> {
                    Log.d("๊ถŒํ•œ", "๋ชจ๋“  ๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
    
                }
                    ActivityCompat.shouldShowRequestPermissionRationale(
                        this, Manifest.permission.ACCESS_FINE_LOCATION
                    ) -> {
                    showPermissionContextPopup()
    
              }
                else -> {
                  requestPermissionResult.launch(permissionList)
                }
            }
        }
      private fun showPermissionContextPopup(){
            androidx.appcompat.app.AlertDialog.Builder(this)
                .setTitle("์œ„์น˜ ๊ถŒํ•œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค")
                .setMessage("๊ท€ํ•˜์˜ ์•ˆ์ „์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ์œ„์น˜ ๊ถŒํ•œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.")
                
              // 3. ๋™์˜ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์œ„์น˜ ๊ถŒํ•œ ์š”์ฒญ
                .setPositiveButton("๋™์˜") {_,_ ->
                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),0
                    )
                }
                .setNegativeButton("์ทจ์†Œ") {_,_ ->}
                .create()
                .show()
        }

     

    ๊ฒฐ๊ณผ

    ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ์ด์œ ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ฐฝ๊ณผ ๋™์˜ ์‹œ ๊ถŒํ•œ ์š”์ฒญ ์ฐฝ์— ๋œฌ ํ™”๋ฉด

    728x90