image_picker: ^1.1.2
gal: ^2.3.2
패키지 설명:
| 패키지 | 용도 | 특징 |
| image_picker | 카메라나 갤러리에서 이미지 선택 | 크로스 플랫폼 지원, 안정적인 성능 |
| gal | 이미지나 비디오를 갤러리에 저장 | gallery_saver의 개선된 버전, 최신 AGP 지원 |
권한 설정
Android (android/app/src/main/AndroidManifest.xml)\
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
iOS (ios/Runner/Info.plist)
<key>NSCameraUsageDescription</key>
<string>카메라를 사용하여 사진을 촬영합니다.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>사진을 갤러리에 저장합니다.</string>
AGP 오류 확인
│ [!] This is likely due to a known bug in Android Gradle Plugin (AGP) versions less than 8.2.1, │
│ when │
│ 1. setting a value for SourceCompatibility and │
│ 2. using Java 21 or above.
해결 방안
settings.gradle 파일 확인
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.5.0" apply false #수정
id "org.jetbrains.kotlin.android" version "1.9.10" apply false #수정
}
gradle/gradle-wrapper.propertise
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
수정 후 명령어 입력
# 1. 캐시 완전 정리
flutter clean
# 2. 의존성 다시 설치
flutter pub get
# 3. 빌드 테스트
flutter run
0
import 'package:flutter/material.dart';
import 'package:gal/gal.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String statusMessage = "사진 저장하기";
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: Center(
child: Text(
statusMessage,
style: TextStyle(fontSize: 40),
),
),
),
Row(
children: [
IconButton(
onPressed: _takePhoto,
icon: Icon(
Icons.camera_alt_outlined,
size: 50,
),
)
],
)
],
),
),
),
);
}
void _takePhoto() async {
setState(() {
statusMessage = "카메라 준비중 ...";
});
try {
// 갤러리 접근 권한 확인 요청
if (await Gal.hasAccess() == false) {
await Gal.requestAccess();
}
// 카메라에서 사진 촬영 요청
// source - 사진 촬영
// source - 갤러리에서 이미지 선택
XFile? image = await ImagePicker().pickImage(
source: ImageSource.camera,
imageQuality: 85,
);
if (image != null) {
print("저장 경로: ${image.path}");
setState(() {
statusMessage = "사진을 저장 중 ... ";
});
// 갤러리(사진첩에 촬용한 사진을 저장한다)
await Gal.putImage(image.path);
Future.delayed(const Duration(seconds: 3), () {
setState(() {
statusMessage = "사진 저장하기";
});
});
}
} catch (e) {
print('오류 발생 $e');
setState(() {
statusMessage = "오류가 발생 했습니다";
});
Future.delayed(const Duration(seconds: 3), () {
setState(() {
statusMessage = "사진 저장하기";
});
});
}
} // end of takePhoto
} // end of class'Flutter' 카테고리의 다른 글
| 카메라 다루기 3단계 (0) | 2025.08.20 |
|---|---|
| 카메라 다루기 2단계 (0) | 2025.08.20 |
| Flutter Key 및 상태 관리의 기본 개념 - 성능 최적화 팁 (0) | 2025.08.20 |
| Flutter Key 및 상태 관리의 기본 개념 - Flutter의 Element 재사용 메커니즘 (0) | 2025.08.19 |
| Flutter Key 및 상태 관리의 기본 개념 - Flutter의 세 가지 트리 구조 (0) | 2025.08.19 |