이미지 접근 (Ios , Android) 권한

2025. 1. 7. 15:40·Flutter
728x90
반응형

앱에서 사용자로부터 이미지 접근 권한을 요청하고 이를 처리하는 방법은 iOS와 Android에서 다르게 작동합니다. 이 글에서는 Flutter를 사용하여 iOS와 Android에서 이미지 접근 권한을 설정하고 구현하는 방법을 공유합니다.


1. iOS 권한 설정

iOS에서는 PermissionHandler 패키지를 사용하여 이미지 접근 권한을 요청할 수 있습니다. 권한 요청을 위해 다음 단계를 수행합니다:

1.1 Info.plist 수정

Info.plist에 다음 권한 요청 메시지를 추가합니다:

xml
코드 복사
<key>NSPhotoLibraryUsageDescription</key> <string>사진 접근 권한이 필요합니다.</string> <key>NSCameraUsageDescription</key> <string>카메라 사용 권한이 필요합니다.</string>

1.2 Podfile 수정

Podfile에서 필요한 권한을 활성화합니다:

post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [ '$(inherited)', 'PERMISSION_PHOTOS=1', # 사진 접근 권한 플래그 'PERMISSION_CAMERA=1', # 카메라 권한 플래그 ] end end end
 
 

이후 pod install 명령어를 실행하여 변경사항을 적용합니다.


2. Android 권한 설정

Android에서는 AndroidManifest.xml 파일에 필요한 권한을 선언합니다.

2.1 AndroidManifest.xml 수정

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" />
 

2.2 requestLegacyExternalStorage 추가 (Android 10 이하 지원)

application 태그 내에 다음 속성을 추가합니다:

<application android:requestLegacyExternalStorage="true" ... > </application>

3. Flutter에서 권한 요청 구현

3.1 PermissionHandler 패키지 설치

pubspec.yaml에 permission_handler를 추가합니다:

dependencies: permission_handler: Version

3.2 PermissionService 클래스 구현

권한 요청을 처리하기 위해 PermissionService 클래스를 작성합니다.

import 'dart:io';
import 'package:memory_on/common/constants/app_logger.dart';
import 'package:permission_handler/permission_handler.dart';

class PermissionService {
  /// 권한 요청 (카메라, 사진, 파일 저장소)
  static Future<Map<String, bool>> requestPermissions() async {
    final Map<String, bool> permissionsStatus = {
      "카메라": false,
      "사진": false,
      "저장소": false,
    };

    if (Platform.isIOS) {
      // iOS 권한 요청
      permissionsStatus["카메라"] = await _requestPermission(Permission.camera);
      permissionsStatus["사진"] = await _requestPermission(Permission.photos);
    } else if (Platform.isAndroid) {
      // Android 권한 요청
      permissionsStatus["카메라"] = await _requestPermission(Permission.camera);

      // Android 11(API 30) 이상: READ_MEDIA_IMAGES 요청
      if (await _isAndroid11OrAbove()) {
        permissionsStatus["사진"] = await _requestPermission(Permission.photos);
        permissionsStatus["저장소"] =
            await _requestPermission(Permission.manageExternalStorage);
      } else {
        // Android 10 이하: READ_EXTERNAL_STORAGE 요청
        permissionsStatus["사진"] =
            await _requestPermission(Permission.storage);
        permissionsStatus["저장소"] =
            await _requestPermission(Permission.storage);
      }
    }

    return permissionsStatus;
  }

  /// Android 11(API 30) 이상 확인
  static Future<bool> _isAndroid11OrAbove() async {
    if (!Platform.isAndroid) return false;
    final int sdkVersion =
        await Permission.storage.status.then((_) => 30); // 강제값 대체
    return sdkVersion >= 30;
  }

  /// 개별 권한 요청
  static Future<bool> _requestPermission(Permission permission) async {
    final status = await permission.status;

    if (status.isGranted) {
      // 이미 권한이 허용된 경우
      logger.i("${permission.toString()} 권한이 허용되었습니다.");
      return true;
    } else if (status.isPermanentlyDenied) {
      // 영구적으로 거부된 경우
      logger.e("${permission.toString()} 권한이 영구적으로 거부되었습니다.");
      return false;
    } else {
      // 권한 요청
      final requestStatus = await permission.request();
      logger.i("${permission.toString()} 권한 요청 결과: ${requestStatus}");
      return requestStatus.isGranted;
    }
  }
}

4. 권한 요청 적용

권한 요청을 사용하는 코드는 다음과 같습니다

Future<void> _pickImages() async {
  // PermissionService를 통해 필요한 권한 요청
  final permissionsStatus = await PermissionService.requestPermissions();

  // 권한 상태 확인
  if (permissionsStatus["사진"] == true) {
    // 갤러리 접근 권한이 허용된 경우
    final ImagePicker picker = ImagePicker();
    final List<XFile>? images = await picker.pickMultiImage();

    if (images != null && images.isNotEmpty) {
      setState(() {
        // 최대 5장까지만 추가
        final int availableSlots = 5 - _selectedImages.length;
        if (images.length > availableSlots) {
          _selectedImages.addAll(
            images.take(availableSlots).map((image) => image.path),
          );
        } else {
          _selectedImages.addAll(images.map((image) => image.path));
        }
      });
    }
  } else {
    // 권한이 거부된 경우 처리
    if (permissionsStatus["사진"] == false) {
      showLoginFailedDialog(
        "갤러리 접근 권한이 필요합니다",
        "갤러리 접근 권한을 허용하지 않으면 파일 첨부가 불가능합니다.\n설정에서 권한을 허용해주세요.",
        context,
      );
    }
  }
}
728x90
반응형
LIST

'Flutter' 카테고리의 다른 글

Flutter에서 반응형 배너 UI와 애니메이션 구현  (2) 2025.01.13
Flutter에서 갤러리 이미지 선택 UI: 간격과 레이아웃 최적화 (이미지 썸네일)  (1) 2025.01.07
iOS Xcode 시뮬레이터 키보드 안보일때  (1) 2025.01.07
상태 관리 ) Riverpod 2 vs Bloc vs GetX  (0) 2024.02.23
Dart 3.0 문법  (1) 2024.02.21
'Flutter' 카테고리의 다른 글
  • Flutter에서 반응형 배너 UI와 애니메이션 구현
  • Flutter에서 갤러리 이미지 선택 UI: 간격과 레이아웃 최적화 (이미지 썸네일)
  • iOS Xcode 시뮬레이터 키보드 안보일때
  • 상태 관리 ) Riverpod 2 vs Bloc vs GetX
Mr. Joo
Mr. Joo
  • Mr. Joo
    삽질의 시작
    Mr. Joo
  • 전체
    오늘
    어제
    • 분류 전체보기 (214) N
      • Flutter (70)
      • Android (9)
      • Swift (4)
      • React (11)
      • 인공지능 (4)
      • CS (10)
      • 개발 뉴스 (103) N
      • IT 기기 (1)
      • 알면 유용한 정보 (2)
  • 인기 글

  • 태그

    오늘의 뉴스
    DART
    오늘의 기술 뉴스
    앱 개발
    Flutter
    뉴스
    Dart 기초
    오늘의 개발 뉴스
    기술
    오늘의 이슈
    개발
    개발 뉴스
    이슈
    뉴스 모음
    기술 뉴스
    앱
    개발 이슈
    react
    앱개발
    플러터
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
Mr. Joo
이미지 접근 (Ios , Android) 권한
상단으로

티스토리툴바