seong
Flutter - flutter_callkit_incoming 라이브러리 사용 ( Fake_call ) 본문
Flutter/Flutter
Flutter - flutter_callkit_incoming 라이브러리 사용 ( Fake_call )
hyeonseong 2024. 9. 25. 10:03전화 화면 기능 및 전화기능을 내가 만든 앱으로 변경 할 수 있다.
보통은 Native기능( Kotlin,Swift ) 로 개발하면 좋겠지만 Flutter에서 한번에 지원해주는 라이브러리가 있어서 우선 사용.
사용 라이브러리 : Flutter_callkit_incoming
- Stream_io 에서 만들어서 지원해주는 패키지이다.
어느정도 신뢰성이 있어서 일단 사용 해보기로 결정
https://pub.dev/packages/flutter_callkit_incoming
1. 필요 라이브러리 추가
pubspec.yaml
dependencies:
flutter:
sdk: flutter
#CallKit 필요 라이브러리
uuid: ^4.5.0
flutter_callkit_incoming: ^2.0.4+1
firebase_messaging: ^15.1.0
firebase_core: ^3.4.0
2. AndroidManifest 추가
외부 서버와 통신을 할 필요가 있다면 아래 권한을 추가
ex) 전화 알림 데이터를 받는 등, 실제 전화 기능을 사용한다면 필수로 추가 해야한다.
<manifest...>
...
<!--
Using for load image from internet
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
3. iOS info.plist 추가
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
<string>remote-notification</string>
<string>processing</string> //you can add this if needed
</array>
4. Firebase 연동
- 사용자에게 알림을 주기 위해서 Firebase를 연동 해주어야한다.
- 아래 들어가서 프로젝트 생성하고 Flutter앱을 추가 해주면 된다, 해당글은 callkit사용을 위해서이기 때문에Firebase 연동에 대해선 패스!
https://console.firebase.google.com/?hl=ko
Firebase콘솔에서 연동 완료 되었으면 아래 처럼 파일이 추가되어 있다.
firebase_options.dart
main함수에서 Firebase 초기화
// 백그라운드 작업은 main함수 위에 작성
// entry-point 필요.
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
CallKitHandler().showCallkitIncoming(const Uuid().v4());
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
5. callkit_handler 작성
import 'package:flutter_callkit_incoming/entities/android_params.dart';
import 'package:flutter_callkit_incoming/entities/call_kit_params.dart';
import 'package:flutter_callkit_incoming/entities/ios_params.dart';
import 'package:flutter_callkit_incoming/entities/notification_params.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
class CallKitHandler {
Future<void> showCallkitIncoming(String uuid) async {
final params = CallKitParams(
id: uuid, // Callkit에서 사용 하는 uuid
nameCaller: 'Fake Call Test', // 발신자 이름
appName: 'Fake Call Test App', // 앱의 이름
handle: '0123456789', // 발신 전화 번호 설정
type: 0, // 통화 유형 0은 전화, 1은 영상통화
duration: 30000, // 30초 동안 안받을 시 끊김 (millisecond단위)
textAccept: 'Accept', // 수락 버튼 Text
textDecline: 'Decline', // 거절 버튼 Text
missedCallNotification: const NotificationParams(
showNotification: true, // 알림 표시 여부
isShowCallback: true, // 알림 재 발신 여부
subtitle: 'Missed call', // 부재중 통화 알림의 부제목
callbackText: 'Call back', // 재발신 버튼 제목
),
extra: <String, dynamic>{'userId': '1a2b3c4d'}, // 추가 정보 Map
headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'}, // HTTP 통신에 사용할 헤더 정보
android: const AndroidParams(
isCustomNotification: false, // UI를 커스텀 한다면 true, 기본 UI는 false
isShowLogo: false,
ringtonePath: 'system_ringtone_default', // 알람 소리 재생 파일 경로, 현재는 기본 벨소리 사용
),
ios: const IOSParams(
iconName: 'Fake Call Test',
handleType: '',
supportsVideo: false, // 비디오 통화 지원 여부
maximumCallGroups: 1, // 한번에 허용되는 통화 그룹 수
maximumCallsPerCallGroup: 1, // 한 통화 그룹에서 허용되는 최대 통화 수
audioSessionMode: 'default',// 오디오 세션 모드 , default = 기본 설정
audioSessionActive: true, // 통화 시작시 오디오 세션 활성화 여부
audioSessionPreferredSampleRate: 44100.0,
audioSessionPreferredIOBufferDuration: 0.005,
supportsDTMF: false, // 통화 중 키패드 입력음 여부
supportsHolding: false, // 통화 보류 가능 여부
supportsGrouping: false, // 그룹 통화 여부
supportsUngrouping: false, // 그룹 통화 개별로 분리 가능한지 여부
ringtonePath: 'system_ringtone_default',// 기본 통화 벨소리
),
);
await FlutterCallkitIncoming.showCallkitIncoming(params);
}
}
테스트 UI 제작
1. HomeScreen
버튼을 클릭하면 Fake 전화가 오도록
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
late final Uuid _uuid;
String? _currentUuid;
late final FirebaseMessaging _firebaseMessaging;
@override
void initState() {
_uuid = const Uuid(); // 랜덤 uuid 생성
initFirebase();
WidgetsBinding.instance.addObserver(this);
//Check call when open app from terminated
checkAndNavigationCallingPage();
super.initState();
}
// 현재 통화중 상태인지 확인 하는 함수
Future<dynamic> getCurrentCall() async {
//check current call from pushkit if possible
var calls = await FlutterCallkitIncoming.activeCalls();
if (calls is List) {
if (calls.isNotEmpty) {
print('DATA: $calls');
_currentUuid = calls[0]['id'];
return calls[0];
} else {
_currentUuid = "";
return null;
}
}
}
//통화중이 아니라면 내가 의도한 페이지로 이동
Future<void> checkAndNavigationCallingPage() async {
var currentCall = await getCurrentCall();
if (currentCall != null) {
if (mounted) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SecondPage(),
),
);
}
}
}
// Firebase 초기화
Future<void> initFirebase() async {
_firebaseMessaging = FirebaseMessaging.instance;
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
print(
'Message title: ${message.notification?.title}, body: ${message.notification?.body}, data: ${message.data}');
_currentUuid = _uuid.v4();
CallKitHandler().showCallkitIncoming(_currentUuid!);
});
_firebaseMessaging.getToken().then((token) {
print('Device Token FCM: $token');
});
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
print(state);
if (state == AppLifecycleState.resumed) {
//Check call when open app from background
checkAndNavigationCallingPage();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
// 전화 걸기
await CallKitHandler().showCallkitIncoming(_currentUuid!);
},
child: Text("Fake 전화 걸기"),
),
),
);
}
}
'Flutter > Flutter' 카테고리의 다른 글
Flutter - Android 뒤로가기 버튼 클릭을 홈버튼과 동일한 효과 내기 (0) | 2024.09.19 |
---|---|
Flutter -권한 요청 iOS PermissionHandler (0) | 2024.09.19 |
Flutter - BottomNav 더블 탭시 화면의 스크롤 가장 위로 보내기 (0) | 2024.08.09 |
Flutter - 사용자 설정 폰트 크기 무시하기 (0) | 2024.07.08 |
Flutter - Flutter with Python (2) 파이썬 결과 값 View로 보여주기 (5) | 2024.05.17 |