플러터:마이크 입력
둘러보기로 이동
검색으로 이동
개요[편집 | 원본 편집]
기기에서 마이크를 사용하는 법.
플랫폼 지원 현황[편집 | 원본 편집]
noise_meter를 이용할건데, 모바일에서만 사용 가능하다.
| 플랫폼 | 지원 여부 | 이유 |
|---|---|---|
| Android | ✅ | 완전 지원 |
| iOS | ✅ | 완전 지원 |
| Windows | ❌ | noise_meter 미지원 |
| Web | ❌ | 마이크 API 제한 |
| macOS | ❓ | |
| Linux | ❓ |
사전준비 권한 설정[편집 | 원본 편집]
권한 부여[편집 | 원본 편집]
| 항목 | 설명 | 비고 |
|---|---|---|
| 안드로이드 | android/app/src/main/AndroidManifest.xml 에 넣는다. |
|
| 아이폰 | ios/Runner/Info.plist에 넣는다. | <key>NSMicrophoneUsageDescription</key>
<string>앱에서 음성 입력을 사용합니다.</string> iOS에선 메시지도 직접 입력할 수 있음.(여기에 사용 목적 명시해야 함.) |
| Windows,
Web |
별도 설정 불필요. 자동으로 팝업이 뜸. |
필요한 패키지 점검[편집 | 원본 편집]
| 항목 | 설명 | 비고 |
|---|---|---|
| 패키지 설치 | # pubspec.yaml
dependencies: flutter: sdk: flutter permission_handler: ^11.3.1 noise_meter: ^5.0.1 |
noise_meter는 db를 읽는다.
아마 시간이 지나면 오래된 버전이라 문제가 발생할 수 있음. flutter pub get |
동작 흐름[편집 | 원본 편집]
- 앱 시작
- 마이크 권한 요청
- 권한 허용 시 NoiseMeter 시작
- 실시간 데시벨 스트림 수신
- UI 업데이트 (setState)
- 정지 버튼으로 스트림 취소
데시벨 측정 예시 코드[편집 | 원본 편집]
마찬가지로 패키지 버전에 따라 함수명이 달라지기도 함. 오래되면 문제가 발생할 수 있음.
// filepath: c:\Temp\for device\decibel_app\lib\main.dart
import 'package:flutter/material.dart';
import 'package:noise_meter/noise_meter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '데시벨 측정기',
home: DecibelMeter(),
);
}
}
class DecibelMeter extends StatefulWidget {
@override
_DecibelMeterState createState() => _DecibelMeterState();
}
class _DecibelMeterState extends State<DecibelMeter> {
double _currentDB = 0.0;
bool _isListening = false;
StreamSubscription<NoiseReading>? _noiseSubscription;
Future<void> _startListening() async {
// 마이크 권한 요청
var status = await Permission.microphone.request();
if (status.isGranted) {
_noiseSubscription = NoiseMeter().noise.listen(
(NoiseReading noiseReading) {
setState(() {
_currentDB = noiseReading.meanDecibel;
});
},
onError: (error) {
print('오류: $error');
},
);
setState(() {
_isListening = true;
});
}
}
void _stopListening() {
_noiseSubscription?.cancel();
setState(() {
_isListening = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('데시벨 측정기'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${_currentDB.toInt()} dB',
style: TextStyle(fontSize: 48),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _isListening ? _stopListening : _startListening,
child: Text(_isListening ? '정지' : '시작'),
),
],
),
),
);
}
}
코드 구조 분석[편집 | 원본 편집]
핵심 클래스들[편집 | 원본 편집]
// 📊 데시벨 읽기
NoiseMeter().noise.listen((NoiseReading reading) {
double db = reading.meanDecibel; // 평균 데시벨
});
// 🔒 권한 요청
Permission.microphone.request();
// 🎛️ 스트림 제어
StreamSubscription<NoiseReading>? subscription;
상태 관리[편집 | 원본 편집]
class _DecibelMeterState extends State<DecibelMeter> {
double _currentDB = 0.0; // 현재 데시벨 값
bool _isListening = false; // 측정 중인지 상태
StreamSubscription<NoiseReading>? _noiseSubscription; // 스트림 구독 객체
}
주요 학습 포인트[편집 | 원본 편집]
1. 스트림(Stream) 패턴[편집 | 원본 편집]
// 스트림 구독
_subscription = NoiseMeter().noise.listen(
(data) => setState(() => _currentDB = data.meanDecibel),
onError: (error) => print('에러: $error'),
);
// 메모리 누수 방지
_subscription?.cancel();
2. 권한 관리[편집 | 원본 편집]
Future<void> _requestPermission() async {
var status = await Permission.microphone.request();
if (status.isGranted) {
// 권한 허용됨
} else if (status.isDenied) {
// 권한 거부됨
} else if (status.isPermanentlyDenied) {
// 영구 거부됨 - 설정으로 유도
openAppSettings();
}
}
3. 생명주기 관리[편집 | 원본 편집]
@override
void dispose() {
_noiseSubscription?.cancel(); // 위젯 해제 시 스트림 정리
super.dispose();
}
데시벨 참고값[편집 | 원본 편집]
| 데시벨(dB) | 소음 수준 | 예시 |
|---|---|---|
| 0-20 | 매우 조용 | 도서관, 속삭임 |
| 20-40 | 조용 | 조용한 사무실 |
| 40-60 | 보통 | 일반 대화 |
| 60-80 | 시끄러움 | TV, 음악 |
| 80-100 | 매우 시끄러움 | 지하철, 공사장 |
| 100+ | 위험 | 콘서트, 제트기 |
UI 개선 아이디어[편집 | 원본 편집]
데시벨 수준별 색상[편집 | 원본 편집]
Color _getDecibelColor(double db) {
if (db < 40) return Colors.green; // 조용
if (db < 70) return Colors.yellow; // 보통
return Colors.red; // 시끄러움
}
프로그레스 바[편집 | 원본 편집]
LinearProgressIndicator(
value: _currentDB / 120.0, // 120dB 기준
backgroundColor: Colors.grey[300],
valueColor: AlwaysStoppedAnimation(_getDecibelColor(_currentDB)),
)
다음 단계 학습[편집 | 원본 편집]
중급 기능[편집 | 원본 편집]
- 📈 실시간 그래프 (charts_flutter)
- 💾 측정값 저장 (shared_preferences)
- 🔔 임계값 알림 (flutter_local_notifications)
고급 기능[편집 | 원본 편집]
- 🎵 주파수 분석 (FFT)
- 📊 통계 분석 (평균, 최대, 최소)
- 🌐 데이터 공유 (Firebase)
완성된 기능[편집 | 원본 편집]
- ✅ 실시간 데시벨 측정
- ✅ 마이크 권한 관리
- ✅ 간단한 시작/정지 제어
- ✅ 크로스 플랫폼 (Android/iOS)
- ✅ 메모리 안전 (스트림 정리)
이 프로젝트로 Flutter의 스트림, 권한, 네이티브 패키지 사용법을 모두 학습할 수 있습니다! 🎉