[Android] Permission

leeehaยท2022๋…„ 10์›” 5์ผ
0
post-thumbnail

Permission์˜ ๊ฐœ๋…

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ์™ธ๋ถ€์˜ ์•ฑ์ธ B๋Š” A์˜ ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๊ทธ๋Ÿฐ๋ฐ A์˜ ์ปดํฌ๋„ŒํŠธ์— ํผ๋ฏธ์…˜์ด ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด, B๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์— ์ œ์•ฝ์ด ์ƒ๊ธด๋‹ค.
  • A๋Š” ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์—์„œ <permission> ํƒœ๊ทธ๋กœ ํŠน์ • ์ปดํฌ๋„ŒํŠธ์— ๊ถŒํ•œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ด๋•Œ B๋Š” <uses-permission> ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๋ฉด, A์˜ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

<permission> ํƒœ๊ทธ

AndroidManifest.xml ํŒŒ์ผ์— ๋“ค์–ด๊ฐ€๋Š”, ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ •

  • name: ํผ๋ฏธ์…˜์˜ ์ด๋ฆ„
  • label, description: ํผ๋ฏธ์…˜์— ๋Œ€ํ•œ ์„ค๋ช…
  • protectionLevel: ๋ณดํ˜ธ ์ˆ˜์ค€
    • normal: ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๋ณดํ˜ธ. ์œ ์ €์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์ด ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ
    • dangerous: ๋†’์€ ์ˆ˜์ค€์˜ ๋ณดํ˜ธ. ์œ ์ €์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
    • signature: ๋™์ผ ํ‚ค๋กœ ์‚ฌ์ธ๋œ ์•ฑ๋งŒ ์‹คํ–‰
    • signatureOrSystem: ๋™์ผ ํ‚ค๋กœ ์‚ฌ์ธ๋œ ์•ฑ์ด๊ฑฐ๋‚˜ ์•ˆ๋“œ๋กœ์ด๋“œ ์‹œ์Šคํ…œ ์•ฑ๋งŒ ์‹คํ–‰

<uses-permission> ํƒœ๊ทธ

๊ถŒํ•œ์ด ์„ค์ •๋œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์™ธ๋ถ€ ์•ฑ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋Š” <uses-permission> ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

์‹œ์Šคํ…œ์—์„œ ์š”๊ตฌ๋˜๋Š” ํผ๋ฏธ์…˜

์™ธ๋ถ€ ์•ฑ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ•„์š”ํ•œ ํผ๋ฏธ์…˜ ๋ง๊ณ ๋„, ์‹œ์Šคํ…œ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ์š”๊ตฌํ•˜๋Š” ํผ๋ฏธ์…˜๋“ค์ด ์žˆ๋‹ค. ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ <uses-permission> ํƒœ๊ทธ๋ฅผ ๊ฑธ์–ด์ค˜์•ผ ํ•œ๋‹ค.

  • ACCESS_FINE_LOCATION: ์œ„์น˜ ์ •๋ณด ์ ‘๊ทผ
  • ACCESS_NETWORK_STATE: ๋„คํŠธ์›Œํฌ ์ •๋ณด ์ ‘๊ทผ
  • ACCESS_WIFI_STATE: ์™€์ดํŒŒ์ด ๋„คํŠธ์›Œํฌ ์ •๋ณด ์ ‘๊ทผ
  • BATTERY_STATS: ๋ฐฐํ„ฐ๋ฆฌ ์ •๋ณด ์ ‘๊ทผ
  • BLUETOOTH: ๋ธ”๋ฃจํˆฌ์Šค ์žฅ์น˜์— ์—ฐ๊ฒฐ
  • BLUETOOTH_ADMIN: ๋ธ”๋ฃจํˆฌ์Šค ์žฅ์น˜๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํŽ˜์–ด๋ง
  • CAMERA: ์นด๋ฉ”๋ผ ์žฅ์น˜์— ์ ‘๊ทผ
  • INTERNET: ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ
  • READ_EXTERNAL_STORAGE: ์™ธ๋ถ€ ์ €์žฅ์†Œ์—์„œ ํŒŒ์ผ ์ฝ๊ธฐ
  • WRITE_EXTERNAL_STORAGE: ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ํŒŒ์ผ ์“ฐ๊ธฐ
  • READ_PHONE_STATE: ์ „ํ™”๊ธฐ์˜ ๊ฐ์ข… ์ •๋ณด ์ ‘๊ทผ
  • SEND_SMS: SMS ๋ฐœ์‹ 
  • RECEIVE_SMS: SMS ์ˆ˜์‹ 
  • RECEIVE_BOOT_COMPLETED: ๋ถ€ํŒ… ์™„๋ฃŒ ์‹œ ์‹คํ–‰
  • VIBRATE: ์ง„๋™ ์šธ๋ฆฌ๊ธฐ

Permission Check

  • API Level 23 ์ด์ „ ๋ฒ„์ „์—์„œ ํผ๋ฏธ์…˜์€ ์‹ ๊ณ ์ œ
    : ๊ฐœ๋ฐœ์ž๊ฐ€ <uses-permission> ํƒœ๊ทธ๋กœ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๊ณ  ์„ ์–ธ๋งŒ ํ•˜๋ฉด, ์œ ์ €๋Š” ์ด๋ฅผ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์—†๊ณ  ๊ทธ๋ƒฅ ์‹คํ–‰์ด ๋จ.
  • API Level 23 ๋ฒ„์ „๋ถ€ํ„ฐ ํผ๋ฏธ์…˜์€ ํ—ˆ๊ฐ€์ œ
    : ์œ ์ €๊ฐ€ ํ™˜๊ฒฝ ์„ค์ •์—์„œ ํผ๋ฏธ์…˜์„ ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ์Œ.
  • ํผ๋ฏธ์…˜ ์ฒดํฌ๋Š” checkSelfPermisssion() ํ•จ์ˆ˜ ์ด์šฉ
  • ๊ฒฐ๊ณผ ๊ฐ’์€ ์ƒ์ˆ˜๋กœ ์ „๋‹ฌ
  • PackageManager.PERMISSION_GRANTED: ํผ๋ฏธ์…˜์ด ํ—ˆ๋ฝ๋œ ๊ฒฝ์šฐ
  • PackageManager.PERMISSION_DENIED: ํผ๋ฏธ์…˜์ด ๊ฑฐ๋ถ€๋œ ๊ฒฝ์šฐ


Permission Request

requestPermissions()

requestPermissions() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์œ ์ €์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์š”์ฒญํ•˜๋Š” ์‹œ์Šคํ…œ ๋‹ค์ด์–ผ๋กœ๊ทธ๊ฐ€ ๋œฌ๋‹ค.

registerForActivityResult()

API Level 31๋ถ€ํ„ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅ


์‹ค์Šต ์˜ˆ์ œ

requestPermissions()

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorial.c51">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AndroidLab">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.kt

package com.tutorial.c51

import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val status = ContextCompat.checkSelfPermission(
            this,
            "android.permission.ACCESS_FINE_LOCATION"
        )

        if(status == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "granted...", Toast.LENGTH_SHORT).show()
        }else{
            // ์š”์ฒญ ๋‹ค์ด์–ผ๋กœ๊ทธ ๋„์šฐ๊ธฐ
            ActivityCompat.requestPermissions(
                this,
                arrayOf("android.permission.ACCESS_FINE_LOCATION"),
                100
            )
        }
    }

    // ์š”์ฒญ ๋‹ค์ด์–ผ๋กœ๊ทธ ์‘๋‹ต ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "granted...", Toast.LENGTH_SHORT).show()
        }else{
            Toast.makeText(this, "denied...", Toast.LENGTH_SHORT).show()
        }
    }
}

registerForActivityResult()

package com.tutorial.c51

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val requestPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ){
            if(it){
                Toast.makeText(this, "granted...", Toast.LENGTH_SHORT).show()
            }else{
                Toast.makeText(this, "denied...", Toast.LENGTH_SHORT).show()
            }
        }

        val status = ContextCompat.checkSelfPermission(
            this,
            "android.permission.ACCESS_FINE_LOCATION"
        )

        if(status == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "granted...", Toast.LENGTH_SHORT).show()
        }else{
            // ์š”์ฒญ ๋‹ค์ด์–ผ๋กœ๊ทธ ๋„์šฐ๊ธฐ
            // test1...
//            ActivityCompat.requestPermissions(
//                this,
//                arrayOf("android.permission.ACCESS_FINE_LOCATION"),
//                100
//            )

            // test2...
            requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        }
    }

    // ์š”์ฒญ ๋‹ค์ด์–ผ๋กœ๊ทธ ์‘๋‹ต ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this, "granted...", Toast.LENGTH_SHORT).show()
        }else{
            Toast.makeText(this, "denied...", Toast.LENGTH_SHORT).show()
        }
    }
}
profile
์Šต๊ด€์ด ๋  ๋•Œ๊นŒ์ง€ ๐Ÿ“

0๊ฐœ์˜ ๋Œ“๊ธ€