permission_manager

์šฉ๋„

์•ฑ์—์„œ ์•จ๋ฒ” ํ˜น์€ ์นด๋ฉ”๋ผ ๋“ฑ ๋„ค์ดํ‹ฐ๋ธŒ ์ž์›์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ํš๋“ ํ•ด์•ผํ•œ๋‹ค. ์ด ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ”๋กœ ๊ถŒํ•œ์„ ์ฃผ๋ฉด ๊น”๋”ํ•œ๋ฐ, ๋งŒ์•ฝ ๊ฑฐ๋ถ€ ํ˜น์€ '๋‹ค์‹œ ๋ฌป์ง€ ์•Š๊ธฐ' ๋“ฑ์œผ๋กœ ์˜์›์ด ๊ฑฐ๋ถ€๋ฅผ ํ•ด๋†“๊ณ ๋Š” ์ •์ž‘ ๊ธฐ๋Šฅ์€ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

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

์ฆ‰, ๋งค๋„๋Ÿฌ์šด ์•ฑ ์‚ฌ์šฉ ํ๋ฆ„์„ ์œ„ํ•ด์„œ ๊ถŒํ•œ ์ƒํƒœ์— ๋Œ€ํ•œ ๊ฒ€์‚ฌ์™€ ๊ฐ ์ƒํƒœ์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

๊ตฌํ˜„

์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ฒจ๋‘”๋‹ค. ํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ์—๋Š” ๊ตฌํ˜„ํ•  ์•ฑ์ด ์–ด๋–ค ๊ถŒํ•œ์„ ์‚ฌ์šฉํ• ์ง€ ์•Œ ์ˆ˜ ์—†์–ด์„œ ์ผ๋‹จ์€ ์ œ์™ธ์‹œ์ผฐ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์•จ๋ฒ”๊ณผ ์นด๋ฉ”๋ผ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์—์„œ ๊ฐ ๊ธฐ๋Šฅ์˜ ์‚ฌ์šฉ ์ „์— ๊ถŒํ•œ ์ฒดํฌ๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ์ด๋‹ค.

permission_handler ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

flutter pub add permission_handler
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:fitsquad_app/barrel.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

class PermissionManager {
  static Future<void> checkPhotoPermission({
    required BuildContext currentBuildContext,
    required Function grantedAction,
  }) async {
    PermissionStatus status = await _checkStatus();

    if (status.isDenied) {
      status = await _requestPermission();

      if (status.isGranted) {
        grantedAction();
      } else if (status.isPermanentlyDenied) {
        Future.microtask(() {
          BasicDialog.show(
            context: currentBuildContext,
            title: TextManager.photoPermissionTitle.tr(),
            contents: TextManager.photoPermissionMessage.tr(),
            confirmAction: () {
              openAppSettings();
            },
          );
        });
      }
    } else if (status.isPermanentlyDenied) {
      Future.microtask(() {
        BasicDialog.show(
          context: currentBuildContext,
          title: TextManager.photoPermissionTitle.tr(),
          contents: TextManager.photoPermissionMessage.tr(),
          confirmAction: () {
            openAppSettings();
          },
        );
      });
    } else if (status.isGranted) {
      grantedAction();
    }
  }

  static Future<PermissionStatus> _checkStatus() async {
    if (Platform.isAndroid) {
      final androidInfo = await DeviceInfoPlugin().androidInfo;
      if (androidInfo.version.sdkInt <= 32) {
        return await Permission.storage.status;
      } else {
        return await Permission.photos.status;
      }
    }

    return await Permission.photos.status;
  }

  static Future<PermissionStatus> _requestPermission() async {
    if (Platform.isAndroid) {
      final androidInfo = await DeviceInfoPlugin().androidInfo;
      if (androidInfo.version.sdkInt <= 32) {
        return await Permission.storage.request();
      } else {
        return await Permission.photos.request();
      }
    }

    return await Permission.photos.request();
  }

  static Future<void> checkCameraPermission({
    required BuildContext currentBuildContext,
    required Function grantedAction,
  }) async {
    PermissionStatus status = await Permission.camera.status;

    if (status.isDenied) {
      status = await Permission.camera.request();

      if (status.isGranted) {
        grantedAction();
      } else if (status.isPermanentlyDenied) {
        Future.microtask(() {
          BasicDialog.show(
            context: currentBuildContext,
            title: TextManager.cameraPermissionTitle.tr(),
            contents: TextManager.cameraPermissionMessage.tr(),
            confirmAction: () {
              openAppSettings();
            },
          );
        });
      }
    } else if (status.isPermanentlyDenied) {
      Future.microtask(() {
        BasicDialog.show(
          context: currentBuildContext,
          title: TextManager.cameraPermissionTitle.tr(),
          contents: TextManager.cameraPermissionMessage.tr(),
          confirmAction: () {
            openAppSettings();
          },
        );
      });
    } else if (status.isGranted) {
      grantedAction();
    }
  }
}

์‚ฌ์šฉ

      onTap: () async {
        if (imageSource == ImageSource.camera) {
          await PermissionManager.checkCameraPermission(
              currentBuildContext: context,
              grantedAction: () async {
                await _takePicture(context, imageSource);
              });
        } else {
          await PermissionManager.checkPhotoPermission(
              currentBuildContext: context,
              grantedAction: () async {
                await _takePicture(context, imageSource);
              });
        }
      },

์ฃผ์˜์‚ฌํ•ญ

permission_handler๋Š” ๊ฐ OS ๋ณ„๋กœ ๊ตฌํ˜„ ํ•ด์ค˜์•ผ ํ•  ๊ฒƒ๋“ค์ด ์ถ”๊ฐ€์ ์œผ๋กœ ์กด์žฌํ•œ๋‹ค. ์ด๋Š” ์–ด๋–ค ๊ถŒํ•œ์„ ์ค˜์•ผ ํ• ์ง€(์–ด๋–ค ๋„ค์ดํ‹ฐ๋ธŒ ์ž์›์„ ๋Œ์–ด๋‹ค ์จ์•ผ ํ•˜๋Š”์ง€)์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์„œ ์—ฌ๊ธฐ์„œ ์ •๋ฆฌ๋Š” ์ƒ๋žตํ•œ๋‹ค.

์ž์„ธํ•œ ๊ฒƒ์€ ๊ณต์‹๋ฌธ์„œ์˜ SetUp ๋ถ€๋ถ„์— ๊ฐ OS ๋ณ„๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ๋‹ค. ๋ฐ˜๋“œ์‹œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผํ•œ๋‹ค.

Last updated