자바 안드로이드 앱개발 강좌, 퍼미션 설정하기

안드로이드 앱을 개발할 때, 특정 기능이나 데이터를 사용하기 위해서는 퍼미션(permission) 설정이 필수적입니다. 이번 강좌에서는 자바를 사용한 안드로이드 앱개발에서 퍼미션 설정의 중요성과 방법에 대해 자세히 알아보겠습니다.

1. 퍼미션의 중요성

퍼미션은 앱이 특정 기능에 접근할 수 있도록 허용하는 권한입니다. 예를 들어, 카메라, 마이크, 위치 정보, 저장소 등에 접근할 때 퍼미션을 요청해야 합니다. 퍼미션을 설정하지 않으면 이러한 기능을 사용할 수 없으며, 사용자 데이터의 보호 및 보안을 강화하는데 중요한 역할을 합니다.

1.1 퍼미션 유형

안드로이드에서는 퍼미션을 크게 두 가지 유형으로 나눌 수 있습니다:

  • 일반 퍼미션 (Normal Permissions): 사용자에게 영향을 미치지 않는 기능으로, 앱 설치 시 자동으로 허용됩니다. 예) 인터넷 접근.
  • 위험 퍼미션 (Dangerous Permissions): 사용자에게 민감한 정보에 접근하는 기능으로, 사용자의 명시적인 허가가 필요합니다. 예) 위치 정보, 카메라 접근.

2. 퍼미션 설정 방법

안드로이드 앱에서 퍼미션을 설정하는 방법에는 두 가지 단계가 있습니다. 종류에 따라 각각의 방법을 살펴보겠습니다.

2.1 AndroidManifest.xml 파일에 퍼미션 선언하기

모든 퍼미션은 먼저 AndroidManifest.xml 파일에 선언해야 합니다. 이 파일은 앱의 기본 정보를 정의하는 파일로, 퍼미션 설정도 이곳에 포함됩니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.myapp">

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

    <application
        ...
    >
        ...
    </application>

</manifest>

2.2 런타임 퍼미션 요청하기

Android 6.0 (API 레벨 23) 이상부터는 위험 퍼미션을 사용할 때 런타임에 사용자의 승인을 요청해야 합니다. 이를 위해 아래의 코드를 사용하여 퍼미션을 요청할 수 있습니다.

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

public class MainActivity extends AppCompatActivity {

    private static final int CAMERA_REQUEST_CODE = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
        } else {
            // 퍼미션이 이미 허용된 경우
            Toast.makeText(this, "카메라 퍼미션이 허용되었습니다.", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "카메라 퍼미션이 허용되었습니다.", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "카메라 퍼미션이 거부되었습니다.", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

위의 코드에서 ContextCompat.checkSelfPermission() 메소드를 사용하여 퍼미션이 이미 허용되었는지 확인하고, ActivityCompat.requestPermissions()를 통해 허가를 요청합니다. 사용자가 허용 또는 거부를 선택하면 onRequestPermissionsResult() 메소드에서 결과를 처리합니다.

3. 퍼미션 처리 예제

아래 예제에서는 카메라 퍼미션을 요청하고, 사용자가 요청을 허용하는 경우 사진을 찍는 기능을 구현해보겠습니다.

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int CAMERA_REQUEST_CODE = 100;
    private static final int IMAGE_CAPTURE_REQUEST = 1;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = findViewById(R.id.imageView);
        Button button = findViewById(R.id.captureButton);

        button.setOnClickListener(v -> {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
            } else {
                openCamera();
            }
        });
    }

    private void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, IMAGE_CAPTURE_REQUEST);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == IMAGE_CAPTURE_REQUEST && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            imageView.setImageBitmap(imageBitmap);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCamera();
            } else {
                Toast.makeText(this, "카메라 퍼미션이 거부되었습니다.", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

이 예제에서 사용자는 카메라 퍼미션을 요청받고, 허용할 경우 카메라 앱이 열리며 사진을 찍을 수 있습니다. 찍은 사진은 ImageView에 표시됩니다.

4. 퍼미션 관련 팁

퍼미션을 사용할 때는 다음과 같은 팁을 고려하는 것이 좋습니다:

  • 최소한의 퍼미션 요청: 사용자가 수락하지 않을 수도 있으므로, 필요한 퍼미션만 요청하도록 합니다.
  • 명확한 이유 제공: 사용자가 퍼미션 요청에 대해 이해할 수 있도록, 왜 해당 퍼미션이 필요한지 설명하는 메시지를 제공하는 것이 좋습니다.
  • 사용자 경험 고려: 퍼미션 요청 시 사용자의 흐름을 방해하지 않도록, 적절한 시점에서 요청하도록 합니다.

5. 결론

이번 강좌에서는 안드로이드 앱에서 퍼미션을 설정하는 방법에 대해 설명하였습니다. 퍼미션은 사용자의 데이터를 보호하는 중요한 요소이기에, 올바르게 설정하고 요청하는 것이 필수적입니다. 앞으로 앱을 개발할 때 이 강좌에서 배운 내용을 잘 활용하시기 바랍니다.

6. 참고자료