[Android] ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ(runtime permissions) ์ฒ˜๋ฆฌ

2025. 9. 14. 00:37ยทAndroid

๐Ÿ‹‍๐ŸŸฉ ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ(Runtime Permissions)

์•ˆ๋“œ๋กœ์ด๋“œ 6.0(API 23) ์ด์ƒ์—์„œ๋Š” ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ(Runtime Permission) ๋˜๋Š” ์œ„ํ—˜ ๊ถŒํ•œ(Dangerous Permission)์ด๋ผ๋Š” ๊ฐœ๋…์ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ‹‍๐ŸŸฉ ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ์ด๋ž€?

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

์•ฑ์—์„œ ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ์„ ์š”์ฒญ ์‹œ ํ‘œ์‹œ๋˜๋Š” ์‹œ์Šคํ…œ ๊ถŒํ•œ ๋ฉ”์‹œ์ง€

 

๐Ÿ‹‍๐ŸŸฉ ์œ„ํ—˜ ๊ถŒํ•œ ์˜ˆ์‹œ

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ๋Œ€๋ถ€๋ถ„์€ ๋ฏผ๊ฐํ•œ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์œ„์น˜ ์ •๋ณด (Location)
  • ์—ฐ๋ฝ์ฒ˜ (Contacts)
  • ๋งˆ์ดํฌ (Microphone)
  • ์นด๋ฉ”๋ผ (Camera)

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

 

๐Ÿ‹‍๐ŸŸฉ ์‹œ์Šคํ…œ ๋ณดํ˜ธ ์ˆ˜์ค€

์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ์„ dangerous(์œ„ํ—˜)๋ณดํ˜ธ ์ˆ˜์ค€์œผ๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.

  • Normal ๊ถŒํ•œ → ์ž๋™ ๋ถ€์—ฌ (์˜ˆ: ์ธํ„ฐ๋„ท ์ ‘๊ทผ)
  • Dangerous ๊ถŒํ•œ → ๋Ÿฐํƒ€์ž„์— ์‚ฌ์šฉ์ž ๋™์˜ ํ•„์š” (์˜ˆ: ์œ„์น˜, ์นด๋ฉ”๋ผ ๋“ฑ)

 

๐Ÿ‹‍๐ŸŸฉ ๊ถŒํ•œ ์ฒ˜๋ฆฌ ๊ฐ€์ด๋“œ

1. ๊ถŒํ•œ ์„ ์–ธ ๋ฐ ํ™•์ธ

๊ถŒํ•œ์„ ์š”์ฒญํ•˜๊ธฐ ์ „์— AndroidManifest.xml์— ํ•ด๋‹น ๊ถŒํ•œ์„ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

๋Ÿฐํƒ€์ž„ ์‹œ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋ฉฐ ์š”์ฒญ ์ „์—๋Š” ๋ฐ˜๋“œ์‹œ ContextCompat.checkSelfPermission()์„ ํ†ตํ•ด ๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ—ˆ์šฉ๋จ → ๊ธฐ๋Šฅ ์‹คํ–‰
  • ํ—ˆ์šฉ๋˜์ง€ ์•Š์Œ → ๊ถŒํ•œ ์š”์ฒญ ์ง„ํ–‰
// ๊ถŒํ•œ ํ™•์ธ ๋ฐ ์š”์ฒญ
fun checkAndRequestPermission() {
    when {
        // ์ด๋ฏธ ๊ถŒํ•œ ์žˆ์Œ
        ContextCompat.checkSelfPermission(
            this, Manifest.permission.CAMERA
        ) == PackageManager.PERMISSION_GRANTED -> {
            startCamera()
        }

        // ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์ด์œ  ์„ค๋ช…
        shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {
            showPermissionExplanationDialog {
                requestPermissionLauncher.launch(Manifest.permission.CAMERA)
            }
        }

        // ๊ถŒํ•œ ์š”์ฒญ
        else -> {
            requestPermissionLauncher.launch(Manifest.permission.CAMERA)
        }
    }
}

2. ๊ถŒํ•œ ์š”์ฒญํ•˜๊ธฐ

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ๊ถŒ์žฅํ•˜๋Š” ์ตœ์‹  ๋ฐฉ์‹์€ ActivityResultLauncher API ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์‹œ์Šคํ…œ์ด ์ž๋™์œผ๋กœ ๊ถŒํ•œ ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ๋„์›Œ์ฃผ๊ณ , ์‚ฌ์šฉ์ž๋Š” ํ—ˆ์šฉ/๊ฑฐ๋ถ€๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์ฝœ๋ฐฑ์œผ๋กœ ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง‘๋‹ˆ๋‹ค.

// ๊ถŒํ•œ ์š”์ฒญ ๋Ÿฐ์ฒ˜ ๋“ฑ๋ก
private val requestPermissionLauncher =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
        if (isGranted) {
            // ๊ถŒํ•œ ํ—ˆ์šฉ๋จ → ๊ธฐ๋Šฅ ์‹คํ–‰
        } else {
            // ๊ถŒํ•œ ๊ฑฐ๋ถ€๋จ → ์‚ฌ์šฉ์ž ์•ˆ๋‚ด
        }
    }

3. ๊ถŒํ•œ ์š”์ฒญ ๊ทผ๊ฑฐ ์ œ๊ณตํ•˜๊ธฐ

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์‹œ์Šคํ…œ์€ shouldShowRequestPermissionRationale()์„ true๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ๋Š” ๊ถŒํ•œ ์š”์ฒญ ์ „, ์‚ฌ์šฉ์ž์—๊ฒŒ ํ•ด๋‹น ๊ธฐ๋Šฅ์— ๊ถŒํ•œ์ด ์™œ ํ•„์š”ํ•œ์ง€ UI๋กœ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์˜ ํ•„์š”์„ฑ์„ ์ดํ•ดํ•˜์—ฌ ๊ถŒํ•œ ํ—ˆ์šฉ ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. ๊ถŒํ•œ ๊ฑฐ๋ถ€ ์ฒ˜๋ฆฌํ•˜๊ธฐ

์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฑฐ๋ถ€ํ•˜๋ฉด, ์•ˆ๋“œ๋กœ์ด๋“œ๋Š” ์ด๋ฅผ ์˜๊ตฌ ๊ฑฐ๋ถ€๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์•ฑ์€ ๋” ์ด์ƒ ๊ถŒํ•œ ์š”์ฒญ ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ๋„์šธ ์ˆ˜ ์—†์œผ๋ฉฐ, ์•ฑ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ธฐ๋Šฅ ์ œํ•œ์„ ๋ช…ํ™•ํžˆ ์•ˆ๋‚ดํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‹œ์Šคํ…œ ์„ค์ • ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ์œ ๋„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Android์—์„œ ๊ถŒํ•œ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋žต์ ์ธ ์›Œํฌํ”Œ๋กœ

[์•ฑ ์‹คํ–‰]
    โ”‚
    โ–ผ
[๊ถŒํ•œ ์„ ์–ธ ํ™•์ธ (Manifest)]
    โ”‚
    โ–ผ
[๊ถŒํ•œ ํ™•์ธ]
 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
 โ”‚               โ”‚                        โ”‚
 โ–ผ               โ–ผ                        โ–ผ
์ด๋ฏธ ํ—ˆ์šฉ๋จ   ์„ค๋ช… ํ•„์š”(true)           ๊ถŒํ•œ ์—†์Œ
(๋ฐ”๋กœ ์‹คํ–‰)   → ๊ทผ๊ฑฐ ํ‘œ์‹œ ํ›„ ์š”์ฒญ       → ๊ถŒํ•œ ์š”์ฒญ
 โ”‚
 โ–ผ
์‚ฌ์šฉ์ž ์‘๋‹ต
 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
 โ”‚               โ”‚                        โ”‚
 โ–ผ               โ–ผ                        โ–ผ
ํ—ˆ์šฉ๋จ        ๊ฑฐ๋ถ€๋จ                  ์˜๊ตฌ ๊ฑฐ๋ถ€๋จ
๊ธฐ๋Šฅ ์‹คํ–‰    → ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€           → ์„ค์ • ํ™”๋ฉด ์œ ๋„

 

 

๐Ÿ”— ์ฐธ๊ณ 

  • Manifest Interview Android
  • https://developer.android.com/guide/topics/permissions/overview?hl=ko#runtime
๋ฐ˜์‘ํ˜•
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'Android' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Android] ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์˜ˆ์™ธ(Exceptions) ์ถ”์ ํ•˜๊ธฐ  (0) 2025.09.17
[Android] ์•ˆ๋“œ๋กœ์ด๋“œ์˜ Looper, Handler, HandlerThread ์ดํ•ดํ•˜๊ธฐ  (0) 2025.09.17
[Android] SparseArray์— ๋Œ€ํ•˜์—ฌ  (0) 2025.09.14
[Android] ActivityManager๋ž€?  (0) 2025.09.13
[Android] ํ™”๋ฉด ํšŒ์ „๊ณผ ๊ฐ™์€ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•  ๋•Œ Activity์— ์ƒ๊ธฐ๋Š” ๋ณ€ํ™”  (0) 2025.08.31
'Android' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Android] ์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ์˜ˆ์™ธ(Exceptions) ์ถ”์ ํ•˜๊ธฐ
  • [Android] ์•ˆ๋“œ๋กœ์ด๋“œ์˜ Looper, Handler, HandlerThread ์ดํ•ดํ•˜๊ธฐ
  • [Android] SparseArray์— ๋Œ€ํ•˜์—ฌ
  • [Android] ActivityManager๋ž€?
yenim
yenim
    ๋ฐ˜์‘ํ˜•
  • yenim
    FOREST, FOR REST
    yenim
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (235)
      • Android (9)
      • Baekjoon (142)
        • ๊ตฌํ˜„ (3)
        • ๋ธŒ๋ฃจํŠธํฌ์Šค (10)
        • BFS (12)
        • DFS (13)
        • ๋ฐฑํŠธ๋ž˜ํ‚น (3)
        • DP (26)
        • ์ตœ์†Œ ์ŠคํŒจ๋‹ ํŠธ๋ฆฌ (1)
        • ์ด๋ถ„ ํƒ์ƒ‰ (10)
        • ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜ (12)
        • ํˆฌํฌ์ธํ„ฐ (2)
        • ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (2)
        • ๋‹ค์ต์ŠคํŠธ๋ผ (1)
        • ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (6)
        • ๋ถ„ํ•  ์ •๋ณต (3)
        • ๋ฌธ์ž์—ด (9)
        • ์ •๋ ฌ (6)
        • ํƒ์ƒ‰ (2)
        • ์ˆ˜ํ•™ (20)
        • ๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ (1)
      • ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค (15)
        • ๊ตฌํ˜„ (4)
        • ๋ธŒ๋ฃจํŠธํฌ์Šค (4)
        • DFS (1)
        • DP (1)
        • HEAP (1)
        • ๋ฌธ์ž์—ด (3)
        • ํ•ด์‹œ (0)
        • ๋น„ํŠธ (1)
      • CS (39)
        • ๊ฐœ๋ฐœ์ƒ์‹ (9)
        • ์ž๋ฃŒ๊ตฌ์กฐ (8)
        • ๋„คํŠธ์›Œํฌ (7)
        • ์šด์˜์ฒด์ œ (5)
        • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (4)
        • ๋””์ž์ธํŒจํ„ด (1)
        • ์•Œ๊ณ ๋ฆฌ์ฆ˜ (5)
      • Programming Languages (3)
        • C & C++ (2)
        • Kotlin (1)
      • ์ทจ์ค€ (7)
      • Git (2)
      • Google Online Challenge (4)
      • ์—๋Ÿฌ ํ•ด๊ฒฐ (6)
      • WEB (0)
      • NOTE (3)
      • DIARY (3)
      • ์•Œ๊ณ ๋ฆฌ์ฆ˜ (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ๐Ÿก HOME
    • โœ๏ธ TIL
  • ๋งํฌ

    • github
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
    ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ์ฝ”ํ…Œ
    ๋ช…ํ’ˆ ์ž๋ฐ”ํ”„๋กœ๊ทธ๋ž˜๋ฐ
    ๋ฌธ์ž์—ด
    CS
    ๋ธŒ๋ฃจํŠธํฌ์Šค
    ๊ทธ๋ž˜ํ”„
    BFS
    ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ
    DFS
    DP
    ๋„ˆ๋น„์šฐ์„ ํƒ์ƒ‰
    ๊นŠ์ด์šฐ์„ ํƒ์ƒ‰
    ๋ฐฑ์ค€
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.4
yenim
[Android] ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ(runtime permissions) ์ฒ˜๋ฆฌ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”