|
|
|
@ -19,9 +19,8 @@ import 'package:firebase_messaging/firebase_messaging.dart' as fir;
|
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter_ios_voip_kit/call_state_type.dart';
|
|
|
|
|
import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart';
|
|
|
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
|
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
|
import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
|
|
|
|
|
import 'package:huawei_push/huawei_push.dart' as h_push;
|
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
@ -30,6 +29,7 @@ import 'app_shared_preferences.dart';
|
|
|
|
|
import 'navigation_service.dart';
|
|
|
|
|
|
|
|
|
|
// |--> Push Notification Background
|
|
|
|
|
@pragma('vm:entry-point')
|
|
|
|
|
Future<dynamic> backgroundMessageHandler(dynamic message) async {
|
|
|
|
|
print("Firebase backgroundMessageHandler!!!");
|
|
|
|
|
fir.RemoteMessage message_;
|
|
|
|
@ -48,26 +48,14 @@ Future<dynamic> backgroundMessageHandler(dynamic message) async {
|
|
|
|
|
notification.createdOn = DateUtil.convertDateToString(DateTime.now());
|
|
|
|
|
notification.messageTypeData = message.data['picture'];
|
|
|
|
|
notification.message = message.data['message'];
|
|
|
|
|
|
|
|
|
|
await NavigationService.navigateToPage(NotificationsDetailsPage(
|
|
|
|
|
notification: notification,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pragma('vm:entry-point')
|
|
|
|
|
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
|
|
|
|
// await FirebaseMessaging.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
|
|
|
|
// await setupFlutterNotifications();
|
|
|
|
|
// showFlutterNotification(message);
|
|
|
|
|
// If you're going to use other Firebase services in the background, such as Firestore,
|
|
|
|
|
// make sure you call `initializeApp` before using other Firebase services.
|
|
|
|
|
print('Handling a background message ${message.messageId}');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Push Notification Background <--|
|
|
|
|
|
late AndroidNotificationChannel channel;
|
|
|
|
|
|
|
|
|
|
RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) {
|
|
|
|
|
final payload_data = jsonDecode(message.data!);
|
|
|
|
|
final fire_message = RemoteMessage(
|
|
|
|
@ -118,8 +106,12 @@ _incomingCall(Map<String, dynamic> data) async {
|
|
|
|
|
LandingPage.incomingCallData = IncomingCallData.fromJson(data);
|
|
|
|
|
if (LandingPage.isOpenCallPage == false) {
|
|
|
|
|
LandingPage.isOpenCallPage = true;
|
|
|
|
|
final permited = await AppPermission.askVideoCallPermission(currentContext!);
|
|
|
|
|
if (permited) await NavigationService.navigateToPage(IncomingCall(incomingCallData: LandingPage.incomingCallData));
|
|
|
|
|
final bool permited = await AppPermission.askVideoCallPermission(currentContext!);
|
|
|
|
|
if (permited)
|
|
|
|
|
await NavigationService.navigateToPage(
|
|
|
|
|
IncomingCall(incomingCallData: LandingPage.incomingCallData),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
LandingPage.isOpenCallPage = false;
|
|
|
|
|
}
|
|
|
|
|
await Future.delayed(Duration(milliseconds: 500));
|
|
|
|
@ -130,7 +122,6 @@ class PushNotificationHandler {
|
|
|
|
|
late BuildContext context;
|
|
|
|
|
static final PushNotificationHandler _instance = PushNotificationHandler._internal();
|
|
|
|
|
|
|
|
|
|
final voIPKit = FlutterIOSVoIPKit.instance;
|
|
|
|
|
late HmsApiAvailability hmsApiAvailability;
|
|
|
|
|
|
|
|
|
|
late Timer timeOutTimer;
|
|
|
|
@ -162,104 +153,10 @@ class PushNotificationHandler {
|
|
|
|
|
|
|
|
|
|
static PushNotificationHandler getInstance() => _instance;
|
|
|
|
|
|
|
|
|
|
void _timeOut({
|
|
|
|
|
int seconds = 15,
|
|
|
|
|
}) async {
|
|
|
|
|
timeOutTimer = Timer(Duration(seconds: seconds), () async {
|
|
|
|
|
print('🎈 example: timeOut');
|
|
|
|
|
final incomingCallerName = await voIPKit.getIncomingCallerName();
|
|
|
|
|
voIPKit.unansweredIncomingCall(
|
|
|
|
|
skipLocalNotification: false,
|
|
|
|
|
missedCallTitle: '📞 Missed call',
|
|
|
|
|
missedCallBody: 'There was a call from $incomingCallerName',
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init(BuildContext context) async {
|
|
|
|
|
|
|
|
|
|
this.context = context;
|
|
|
|
|
|
|
|
|
|
// VoIP Callbacks
|
|
|
|
|
voIPKit.getVoIPToken().then((value) {
|
|
|
|
|
print('🎈 example: getVoIPToken: $value');
|
|
|
|
|
if (value != null) {
|
|
|
|
|
AppSharedPreferences().setString(APNS_TOKEN, value);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
voIPKit.onDidUpdatePushToken = (
|
|
|
|
|
String token,
|
|
|
|
|
) {
|
|
|
|
|
print('🎈 example: onDidUpdatePushToken: $token');
|
|
|
|
|
AppSharedPreferences().setString(APNS_TOKEN, token);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
voIPKit.onDidReceiveIncomingPush = (
|
|
|
|
|
Map<String, dynamic> payload,
|
|
|
|
|
) async {
|
|
|
|
|
print('🎈 example: onDidReceiveIncomingPush $payload');
|
|
|
|
|
_timeOut();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
voIPKit.onDidRejectIncomingCall = (
|
|
|
|
|
String uuid,
|
|
|
|
|
String callerId,
|
|
|
|
|
) {
|
|
|
|
|
if (isTalking) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print('🎈 example: onDidRejectIncomingCall $uuid, $callerId');
|
|
|
|
|
voIPKit.endCall();
|
|
|
|
|
timeOutTimer?.cancel();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
voIPKit.onDidAcceptIncomingCall = (
|
|
|
|
|
String uuid,
|
|
|
|
|
String callerId,
|
|
|
|
|
) {
|
|
|
|
|
print('🎈 example: onDidAcceptIncomingCall $uuid, $callerId');
|
|
|
|
|
|
|
|
|
|
String sessionID = callerId.split("*")[0];
|
|
|
|
|
String token = callerId.split("*")[1];
|
|
|
|
|
// String isWebRTC = callerId.split("*")[2];
|
|
|
|
|
|
|
|
|
|
print("🎈 SessionID: $sessionID");
|
|
|
|
|
print("🎈 Token: $token");
|
|
|
|
|
|
|
|
|
|
voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
|
|
|
|
|
voIPKit.callConnected();
|
|
|
|
|
timeOutTimer?.cancel();
|
|
|
|
|
|
|
|
|
|
print("🎈 CALL ACCEPTED!!!");
|
|
|
|
|
|
|
|
|
|
Future.delayed(new Duration(milliseconds: 2000)).then((value) async {
|
|
|
|
|
print("🎈 Incoming Call!!!");
|
|
|
|
|
// callPage(sessionID, token, isWebRTC, callerId);
|
|
|
|
|
callPage(sessionID, token);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// if (Platform.isAndroid && (!await FlutterHmsGmsAvailability.isHmsAvailable)) {
|
|
|
|
|
if (Platform.isAndroid) {
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
channel = const AndroidNotificationChannel(
|
|
|
|
|
'high_importance_channel', // id
|
|
|
|
|
'High Importance Notifications', // title
|
|
|
|
|
description:
|
|
|
|
|
'This channel is used for important notifications.', // description
|
|
|
|
|
importance: Importance.high,
|
|
|
|
|
);
|
|
|
|
|
await flutterLocalNotificationsPlugin
|
|
|
|
|
.resolvePlatformSpecificImplementation<
|
|
|
|
|
AndroidFlutterLocalNotificationsPlugin>()
|
|
|
|
|
?.createNotificationChannel(channel);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(await Utils.isGoogleServicesAvailable())) {
|
|
|
|
|
h_push.Push.enableLogger();
|
|
|
|
|
final result = await h_push.Push.setAutoInitEnabled(true);
|
|
|
|
@ -282,7 +179,9 @@ class PushNotificationHandler {
|
|
|
|
|
final fcmToken = await FirebaseMessaging.instance.getToken();
|
|
|
|
|
if (fcmToken != null) onToken(fcmToken);
|
|
|
|
|
}
|
|
|
|
|
} catch (ex) {}
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
print("Notification Exception: " + ex.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Platform.isIOS) {
|
|
|
|
@ -327,19 +226,17 @@ class PushNotificationHandler {
|
|
|
|
|
newMessage(message);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
|
|
|
|
|
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
|
|
|
|
|
|
|
|
|
|
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
|
|
|
|
|
print("Push Notification onTokenRefresh: " + fcm_token);
|
|
|
|
|
onToken(fcm_token);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) {
|
|
|
|
|
print("Push Notification getToken: " + token!);
|
|
|
|
|
onToken(token!);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
|
|
|
|
// FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) {
|
|
|
|
|
// print("Push Notification getToken: " + token!);
|
|
|
|
|
// onToken(token!);
|
|
|
|
|
// });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newMessage(RemoteMessage remoteMessage) async {
|
|
|
|
@ -379,21 +276,15 @@ class PushNotificationHandler {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> isAndroidPermissionGranted() async {
|
|
|
|
|
if (Platform.isAndroid) {
|
|
|
|
|
// final bool granted = await flutterLocalNotificationsPlugin.resolvePlatfxormSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.areNotificationsEnabled() ?? false;
|
|
|
|
|
// if (!granted) {
|
|
|
|
|
// await requestPermissions();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> requestPermissions() async {
|
|
|
|
|
try {
|
|
|
|
|
if (Platform.isIOS) {
|
|
|
|
|
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
|
|
|
|
|
} else if (Platform.isAndroid) {
|
|
|
|
|
Permission.notification.request();
|
|
|
|
|
await Permission.notification.request();
|
|
|
|
|
await Permission.camera.request();
|
|
|
|
|
await Permission.audio.request();
|
|
|
|
|
await Permission.microphone.request();
|
|
|
|
|
}
|
|
|
|
|
} catch (_) {
|
|
|
|
|
debugPrint(_.toString());
|
|
|
|
|