Android ๊ถŒํ•œ Overview

์™œ ๊ถŒํ•œ์ด ํ•„์š”ํ•œ๊ฐ€?

๋ชจ๋“  Android ์•ฑ์€ ์•ก์„ธ์Šค๊ฐ€ ์ œํ•œ๋œ ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ ์‹คํ–‰๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์•ฑ์ด ์ž์‹ ์˜ ์ƒŒ๋“œ๋ฐ•์Šค ์™ธ๋ถ€์˜ ๋ฆฌ์†Œ์Šค๋‚˜ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ์‹œ์Šคํ…œ ๋ณด์•ˆ ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•˜๋ฉฐ ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ์— ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์•ˆ๋“œ๋กœ์ด๋“œ ๊ถŒํ•œ ์š”์ฒญ workflow

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

  1. ์„ค์น˜ ์‹œ๊ฐ„ ๊ถŒํ•œ(Install-time Permission)
    • ์‹œ์Šคํ…œ์ด ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์„ ์„ค์น˜ํ•  ๋•Œ ์ž๋™์œผ๋กœ ์•ฑ์— ๊ถŒํ•œ์„ ๋ถ€์—ฌ
    • ์•ฑ ์Šคํ† ์–ด ์„ธ๋ถ€ ์ •๋ณด์— ์ ‘๊ทผ ๊ถŒํ•œ ํ‘œ๊ธฐ๋จ
    • mainfest์— ์„ ์–ธ๋งŒ ํ•˜๋ฉด ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ
    • ์ผ๋ฐ˜๊ถŒํ•œ๊ณผ ์„œ๋ช…๊ถŒํ•œ ๋“ฑ์œผ๋กœ ๊ตฌ๋ถ„๋จ
      • ์ผ๋ฐ˜๊ถŒํ•œ(Normal Permission)
        • ์•ฑ์˜ ์ƒŒ๋“œ๋ฐ•์Šค ์ด์ƒ์œผ๋กœ ํ™•์žฅ๋œ ๋ฐ์ดํ„ฐ์™€ ์ž‘์—…์— ์•ก์„ธ์Šค
        • ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ์ •๋ณด์™€ ๋‹ค๋ฅธ ์•ฑ ์ž‘์—…์—๋Š” ๊ฑฐ์˜ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Œ
        • ์˜ˆ๋ฅผ ๋“ค์–ด ์ธํ„ฐ๋„ท ๊ถŒํ•œ(INTERNET)์ด๋‚˜, ์ง„๋™ ๊ถŒํ•œ(VIVRATE) ๋“ฑ
        • protectionLevel="normal"
      • ์„œ๋ช… ๊ถŒํ•œ(Signiture Permission)
        • ๊ถŒํ•œ ์ •์˜ํ•˜๋Š” ์•ฑ์ด๋‚˜ OS์™€ ๋™์ผ ์ธ์ฆ์„œ๋กœ ์•ฑ์ด ์„œ๋ช…๋œ ๊ฒฝ์šฐ์—๋งŒ ์•ฑ์— ์„œ๋ช… ๊ถŒํ•œ์„ ๋ถ€์—ฌ
        • ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์–ด๋–ค ๋‹ค๋ฅธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋™์ผํ•œ keystore๋กœ ์ธ์ฆ๋˜์–ด์•ผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ
        • ์˜ˆ๋ฅผ ๋“ค์–ด ์ž๋™์™„์„ฑ, VPN์„œ๋น„์Šค ๋“ฑ
        • protectionLevel"signiture"
  2. ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ(์œ„ํ—˜ ๊ถŒํ•œ)(Runtime Permission)
    • ์•ฑ์—์„œ ์ œํ•œ๋œ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์•ฑ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ๊ถŒํ•œ.
    • ๊ด€๋ จ ๊ธฐ๋Šฅ์— ์•ก์„ธ์Šค ํ•  ๋•Œ๋งˆ๋‹ค ๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•จ.
    • ์˜ˆ๋ฅผ ๋“ค์–ด ๋งˆ์ดํฌ,์นด๋ฉ”๋ผ
    • protectionLevel="danger"
  3. ํŠน๋ณ„ ๊ถŒํ•œ
    • ํŠน์ • ์•ฑ ์ž‘์—…์— ๊ด€ํ•œ ๊ถŒํ•œ
    • ํ”Œ๋žซํผ, OEM๋งŒ ์ •์˜ ๊ฐ€๋Šฅ
    • ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค๋ฅธ ์•ฑ ์œ„์— ๊ทธ๋ฆฌ๊ธฐ ๊ฐ™์€ ์ž‘์—… ๊ถŒํ•œ
    • protectionLevel="appop"

๊ถŒํ•œ ๊ทธ๋ฃน

  • ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ด€๋ จ์„ฑ ์žˆ๋Š” ๊ถŒํ•œ์˜ ์ง‘ํ•ฉ
  • ๊ถŒํ•œ ๊ทธ๋ฃน์€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ๊ธฐ๋ณธ ์›์น™

  • ์‚ฌ์šฉ์ž ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๊ณผ ์ƒํ˜ธ์ž‘์šฉ ์‹œ์ž‘ ์‹œ ๊ถŒํ•œ ์š”์ฒญ
  • ์‚ฌ์šฉ์ž ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ธฐ
  • ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์„ ๊ฑฐ๋ถ€ํ•˜๋ฉด ์•ฑ ์„ฑ๋Šฅ์„ ๋‹จ๊ณ„์ ์œผ๋กœ ์ €ํ•˜ ์‹œ์ผœ ์•ฑ์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ
  • ์‹œ์Šคํ…œ ๋™์ž‘์„ ๊ฐ€์ •ํ•˜์ง€ ์•Š๊ธฐ

๊ถŒ์žฅ ์‚ฌํ•ญ

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

์•ฑ ๊ถŒํ•œ ์„ ์–ธ

  • manifest.xml ํŒŒ์ผ์˜ <uses-permission>์„ ํ™œ์šฉํ•ด ๊ถŒํ•œ์„ ์„ ์–ธ
<manifest ...>
    <uses-permission android:name="android.permission.CAMERA"/>
    <application ...>
        ...
    </application>
</manifest>

ํ•˜๋“œ์›จ์–ด ์„ ํƒ ์‚ฌํ•ญ์œผ๋กœ ์„ค์ •

ํ•˜๋“œ์›จ์–ด๊ฐ€ ํ•„์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ํ‘œ๊ธฐํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ํ•˜๋“œ์›จ์–ด๊ฐ€ ์—†๋Š” ๊ธฐ๊ธฐ์—์„œ ์•ฑ์„ ์„ค์น˜ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•œ๋‹ค.

<manifest ...>
		<uses-permission android:name="android.permission.CAMERA"/>
    <application>
        ...
    </application>
    <uses-feature android:name="android.hardware.camera"
                  android:required="false" />
<manifest>

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

if(applicationContext.packageManager.hasSystemFeature(
			PackageManager.FEATURE_CAMERA_FRONT)){
	//์นด๋ฉ”๋ผ๊ฐ€ ์žˆ๋Š”๊ฒฝ์šฐ
}else{
	//์นด๋ฉ”๋ผ ์—†๋Š” ๊ฒฝ์šฐ
}

API ์ˆ˜์ค€๋ณ„ ๊ถŒํ•œ ์„ ์–ธ

์•ˆ๋“œ๋กœ์ด๋“œ 6.0 (API์ˆ˜์ค€ 23) ์ด์ƒ์„ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๊ธฐ์—์„œ๋งŒ ๊ถŒํ•œ์„ ์„ ์–ธํ•˜๋ ค๋ฉด <uses-permssion-sdk-23> ์ด๊ฑธ๋กœ ๊ถŒํ•œ์„ ์„ ์–ธํ•œ๋‹ค.

ํ˜น์€ maxSdkVersion์„ ํ™œ์šฉํ•˜์—ฌ ์ง€์ •๋œ ๊ฐ’๋ณด๋‹ค ๋†’์€ ๋ฒ„์ „์„ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๊ธฐ์—์„œ ํ•ด๋‹น ๊ถŒํ•œ์„ ์š”์ฒญํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

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

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

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ์š”์ฒญ

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ์š”์ฒญ workflow

๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

  • ContextCompat.checkSelfPermission() ์— ๊ถŒํ•œ ์ „๋‹ฌ
  • ๊ถŒํ•œ์ด ์žˆ๋‹ค๋ฉด PERMISSION_GRANTED๋ฐ˜ํ™˜
  • ์—†๋‹ค๋ฉด PERMISSION_DENIED๋ฐ˜ํ™˜

์•ฑ์— ๊ถŒํ•œ์ด ํ•„์š”ํ•œ ์ด์œ  ์„ค๋ช…

  • shouldShowReuqestPermissionRationale() ํ˜ธ์ถœ
  • ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญ์„ ๋ช…์‹œ์ ์œผ๋กœ ๊ฑฐ๋ถ€ํ•œ ๊ฒฝ์šฐ true๋ฅผ ๋ฐ˜ํ™˜, ์ด ๊ฒฝ์šฐ ์™œ ์ด ๊ถŒํ•œ์ด ํ•„์š”ํ•œ์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„ค๋ช…
  • ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ์š”์ฒญ์„ ์ฒ˜์Œ ๋ณด๊ฑฐ๋‚˜, ๋‹ค์‹œ ๋ฌป์ง€ ์•Š์Œ์„ ์„ ํƒํ•œ ๊ฒฝ์šฐ, ๊ถŒํ•œ์„ ํ—ˆ์šฉํ•œ ๊ฒฝ์šฐ false๋ฅผ ๋ฐ˜ํ™˜

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

  • AndroidX๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ RequestPermission Contract์‚ฌ์šฉ
val requestPermissionLauncher=registerForActivityResult(RequestPermission()){isGranted:Boolean->
	if(isGranted){
		//๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์—ˆ์„๋•Œ ํ”Œ๋กœ์šฐ
	}else{
		//๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์„๋•Œ ํ”Œ๋กœ์šฐ
	}
	
}

//๊ถŒํ•œ ์š”์ฒญ ํ•„์š”์‹œ
requestPermissionLauncher.launch()
  • ๊ถŒํ•œ ๊ทธ๋ฃน์ธ ๊ฒฝ์šฐ RequestMultiplePermissions์‚ฌ์šฉ
  • ๊ถŒํ•œ ๊ด€๋ จ๋œ ์‹œ์Šคํ…œ ๋‹ค์ด์–ผ๋กœ๊ทธ๋Š” ์ปค์Šคํ…€ ๋ถˆ๊ฐ€๋Šฅ์ด๋ฏ€๋กœ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด ๋“ฑ์ด ํ•„์š”ํ•˜๋ฉด ์•ฑ UI๋ฅผ ์ˆ˜์ •

๐Ÿšจย ์ฐธ๊ณ ๋กœ ActivityResultLauncher์˜ ๊ฒฝ์šฐ STARTED์ด์ „์— ํ˜ธ์ถœ ๋˜์–ด์•ผํ•œ๋‹ค. ์•„๋‹ˆ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜จ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด setContent๋‚ด๋ถ€์˜ UI์ฝ”๋“œ๋Š” onResume์—์„œ๋„ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฑฐ๊ธฐ์—๋Š” ์“ฐ๋ฉด ์•ˆ๋œ๋‹ค.

java.lang.IllegalStateException: LifecycleOwner kr.co.gogumac.playgroundforandroid.MainActivity@3474afb is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ์š”์ฒญ ์˜ˆ์ œ ์ฝ”๋“œ

val requestPermissionLauncher=registerForActivityResult(ActivityResultContracts.RequestPermission()){isGranted:Boolean->
	if(isGranted){
		//๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์—ˆ์„๋•Œ ํ”Œ๋กœ์šฐ
	}else{
		//๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋˜์—ˆ์„๋•Œ ํ”Œ๋กœ์šฐ
	}	
}

//...

when{
	ContextCompat.checkSelfPermission(context,Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED->{
		//๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ๋œ ๊ฒฝ์šฐ
	}
	ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)->{
		//๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์ง€ ์•Š์•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๊ฑฐ๋ถ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๊ฒฝ์šฐ
		//์ด ๊ฒฝ์šฐ ํ•ด๋‹น ๊ถŒํ•œ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์•ผํ•จ
		showInContextUI()
	}
	else->{
		//์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ์š”์ฒญ์„ ์ฒ˜์Œ ์ ‘ํ•˜๊ฑฐ๋‚˜, ๋‹ค์‹œ ๋ฌป์ง€ ์•Š์Œ์„ ์„ ํƒํ•œ ๊ฒฝ์šฐ
		requestPermissionLauncher.launch(Manifest.permission.CAMERA)
	}
}

request code๋ฅผ ์‚ฌ์šฉํ•œ ๊ถŒํ•œ ์š”์ฒญ

  • ์œ„ ์˜ˆ์‹œ์—์„œ๋Š” ์‹œ์Šคํ…œ์ด request code๋ฅผ ๊ด€๋ฆฌํ•จ, ์—ฌ๊ธฐ์„œ๋Š” ์ง์ ‘ ๊ด€๋ฆฌ
  • requestPermissions()์‚ฌ์šฉ
when{
	ContextCompat.checkSelfPermission(context,Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED->{
		//๊ถŒํ•œ์ด ์ด๋ฏธ ๋ถ€์—ฌ๋œ ๊ฒฝ์šฐ
	}
	ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)->{
		//๊ถŒํ•œ์ด ๋ถ€์—ฌ๋˜์ง€ ์•Š์•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๊ฑฐ๋ถ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๊ฒฝ์šฐ
		//์ด ๊ฒฝ์šฐ ํ•ด๋‹น ๊ถŒํ•œ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์•ผํ•จ
		showInContextUI()
	}
	else->{
		//์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ ์š”์ฒญ์„ ์ฒ˜์Œ ์ ‘ํ•˜๊ฑฐ๋‚˜, ๋‹ค์‹œ ๋ฌป์ง€ ์•Š์Œ์„ ์„ ํƒํ•œ ๊ฒฝ์šฐ
		requestPermission(context,arrayOf(Manifest.permission.CAMERA,999) //requestCode=999
	}
}
//์š”์ฒญ ๊ฒฐ๊ณผ ๋ฐ›์„๋•Œ

override fun on RequestPermissionResult(requestCode:Int,permissions:Array<String>,grantResults:IntArray){
	when(requestCode){
		999->{
			if((grantResult.isNotEmpty())&&grantResult[0]==PackageManager.PERMISSION_GRANTED)){
				//๊ถŒํ•œ ํ—ˆ์šฉ๋œ ๊ฒฝ์šฐ
			}else{
				//์œ ์ €์—๊ฒŒ ๊ถŒํ•œ ๊ฑฐ๋ถ€๋กœ ์ธํ•ด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค๊ณ  ์„ค๋ช….
				//์œ ์ €์˜ ๊ฒฐ์ •์„ ์กด์ค‘ํ•˜์—ฌ ์‹œ์Šคํ…œ ์„ธํŒ…์œผ๋กœ ์œ ์ €๋ฅผ ์ด๋™์‹œ์ผœ์„œ ์œ ์ € ๊ฒฐ์ •์„ ๋ฐ”๊พธ๋ ค๋Š” ๋…ธ๋ ฅ์„ ํ•˜์ง€ ์•Š์•„์•ผํ•จ.
			}
		}
	}
}
  • ์š”์ฒญ ์‹คํŒจ ์‹œ ๋นˆ ๋ฐฐ์—ด์ด ๋“ค์–ด์˜จ๋‹ค.

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

  1. ํ•ด๋‹น ๊ถŒํ•œ์ด ์—†์–ด์„œ ์ œํ•œ ๋œ ์•ฑ UIํŠน์ • ๋ถ€๋ถ„์„ ๊ฐ•์กฐ
  2. ์ž์„ธํžˆ ์„ค๋ช…
  3. ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ธฐ ex) ์ „์ฒด ํ™”๋ฉด ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€ X
  • ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ๊ถŒํ•œ์— ๊ด€ํ•ด ๊ฑฐ๋ถ€๋ฅผ ๋‘๋ฒˆ์ด์ƒ ์„ ํƒํ•˜๋ฉด ์ดํ›„ ํ•ด๋‹น ๊ถŒํ•œ์„ ์š”์ฒญํ•  ๋•Œ ์‹œ์Šคํ…œ ๋‹ค์ด์–ผ๋กœ๊ทธ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Œ.
  • ์ด๋Ÿฐ ์ด์œ ๋กœ ๊ผญ ํ•„์š”ํ• ๋•Œ๋งŒ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ ๊ฒƒ

์ผํšŒ์„ฑ ๊ถŒํ•œ

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

์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ถŒํ•œ ์žฌ์„ค์ •

์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ถŒํ•œ ์‚ญ์ œ

  • Android 13(API 33) ์ด์ƒ์—์„œ๋Š” ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ์ด ๋”์ด์ƒ ํ•„์š”์—†๋‹ค๋ฉด ํ•ด๋‹น ๊ถŒํ•œ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Œ
  • ์ด ๊ฒฝ์šฐ revokeSelfPermissionOnKill() , revokeSelfPermissionsOnKill() ์‚ฌ์šฉ
  • ๊ถŒํ•œ ๊ทธ๋ฃน ์‚ญ์ œ์‹œ ๋‚ด๋ถ€์˜ ๋ชจ๋“  ๊ถŒํ•œ์— ๋Œ€ํ•ด ์‚ญ์ œํ•ด์•ผํ•จ

์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ถŒํ•œ ์ž๋™ ์žฌ์„ค์ •

  • Android 11(API 30) ์ด์ƒ์—์„œ๋Š” ๋ช‡๊ฐœ์›”๊ฐ„ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ์„ ์‹œ์Šคํ…œ์ด ์ž๋™์œผ๋กœ ์žฌ์„ค์ •ํ•˜๊ฒŒ ๋˜์–ด์žˆ์Œ.

ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ ๋ชจ๋“  ๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ๋ถ€์—ฌ

adb shell install -g PATH_TO_APK_FILE

์ฐธ๊ณ 

Android์—์„œ์˜ ๊ถŒํ•œ ย |ย  Android Developers

Android ๋ณด์•ˆ ๊ธฐ๋Šฅ ย |ย  Android ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ ย |ย  Android Open Source Project

์•ฑ ๊ถŒํ•œ ์„ ์–ธ ย |ย  Android Developers

๋Ÿฐํƒ€์ž„ ๊ถŒํ•œ ์š”์ฒญ ย |ย  Android Developers

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ