Call Notification Fix

merge-update-with-lab-changes
Aamir Muhammad 2 years ago
parent 542864c89c
commit f211fd5617

@ -43,8 +43,9 @@ var logger = Logger(
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
setupLocator(); setupLocator();
await Firebase.initializeApp();
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
runApp(MyApp()); runApp(MyApp());
} }

@ -40,7 +40,6 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart'; import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -89,14 +88,13 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
///inject the user data ///inject the user data
AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>(); AuthenticatedUserObject authenticatedUserObject = locator<AuthenticatedUserObject>();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging?.instance; final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
final authService = new AuthProvider(); final authService = new AuthProvider();
var event = RobotProvider(); var event = RobotProvider();
var familyFileProvider = family.FamilyFilesProvider(); var familyFileProvider = family.FamilyFilesProvider();
// VoIPKit // VoIPKit
final voIPKit = FlutterIOSVoIPKit.instance;
var dummyCallId = '123456'; var dummyCallId = '123456';
var dummyCallerName = 'Dummy Tester'; var dummyCallerName = 'Dummy Tester';
late Timer timeOutTimer; late Timer timeOutTimer;
@ -132,24 +130,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
); );
} }
void _showRequestAuthLocalNotification() async {
await voIPKit.requestAuthLocalNotification();
}
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',
);
});
}
bool isPageNavigated = false; bool isPageNavigated = false;
late LocationUtils locationUtils; late LocationUtils locationUtils;
@ -218,35 +198,33 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
return; return;
} }
} }
Future.delayed(Duration(seconds: 0),(){ Future.delayed(Duration(seconds: 0), () {
setState(() { setState(() {
if (tab == 5) {
if (tab == 5) { IS_VOICE_COMMAND_CLOSED = false;
IS_VOICE_COMMAND_CLOSED = false; triggerRobot();
triggerRobot();
// pageController.jumpToPage(tab);
} else {
if (currentTab > 0 && tab == 2) {
pageController.jumpToPage(0);
currentTab = tab;
} else if (tab != 0) {
// if (tab == 4 && projectViewModel.isLogin && model.count == 0) {
// AppToast.showErrorToast(message: TranslationBase.of(context).noBookedAppo);
// } else {
pageController.jumpToPage(tab);
currentTab = tab;
// }
} else {
pageController.jumpToPage(tab);
currentTab = tab;
}
// currentTab = tab;
}
});
}); // pageController.jumpToPage(tab);
} else {
if (currentTab > 0 && tab == 2) {
pageController.jumpToPage(0);
currentTab = tab;
} else if (tab != 0) {
// if (tab == 4 && projectViewModel.isLogin && model.count == 0) {
// AppToast.showErrorToast(message: TranslationBase.of(context).noBookedAppo);
// } else {
pageController.jumpToPage(tab);
currentTab = tab;
// }
} else {
pageController.jumpToPage(tab);
currentTab = tab;
}
// currentTab = tab;
}
});
});
projectViewModel.analytics.bottomTabNavigation.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin); projectViewModel.analytics.bottomTabNavigation.log(tabIndex: tab, isLoggedIn: projectViewModel.isLogin);
} }
@ -306,15 +284,15 @@ Future.delayed(Duration(seconds: 0),(){
// HMGNetworkConnectivity(context).start(); // HMGNetworkConnectivity(context).start();
_firebaseMessaging.getToken().then((String? token) { _firebaseMessaging.getToken().then((String? token) {
print("Firebase Token: " + token!); // print("Firebase Token: " + token!);
sharedPref.setString(PUSH_TOKEN, token); // sharedPref.setString(PUSH_TOKEN, token!);
if (Platform.isIOS) { // if (Platform.isIOS) {
voIPKit.getVoIPToken().then((value) { // voIPKit.getVoIPToken().then((value) {
print('🎈 example: getVoIPToken: $value'); // print('🎈 example: getVoIPToken: $value');
AppSharedPreferences().setString(APNS_TOKEN, value!); // AppSharedPreferences().setString(APNS_TOKEN, value!);
getOneSignalVOIPToken(value); // // getOneSignalVOIPToken(value);
}); // });
} // }
if (token != null) { if (token != null) {
DEVICE_TOKEN = token; DEVICE_TOKEN = token;
if (!projectViewModel.isLoginChild) { if (!projectViewModel.isLoginChild) {
@ -438,7 +416,7 @@ Future.delayed(Duration(seconds: 0),(){
String caller = callerId.split("*")[3]; String caller = callerId.split("*")[3];
String receiver = callerId.split("*")[4]; String receiver = callerId.split("*")[4];
String host = callerId.split("*")[5]; String host = callerId.split("*")[5];
// await Navigator.push(context, MaterialPageRoute(builder: (context) => StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host))); // await Navigator.push(context, MaterialPageRoute(builder: (context) => StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host)));
} }
getNotificationCount(token) async { getNotificationCount(token) async {
@ -638,7 +616,7 @@ Future.delayed(Duration(seconds: 0),(){
} }
void checkUserStatus(token) async { void checkUserStatus(token) async {
await PushNotificationHandler.getInstance().isAndroidPermissionGranted(); await PushNotificationHandler.getInstance().requestPermissions();
authService.selectDeviceImei(token).then((SelectDeviceIMEIRES value) => setUserValues(value)); authService.selectDeviceImei(token).then((SelectDeviceIMEIRES value) => setUserValues(value));
if (authenticatedUserObject.isLogin) { if (authenticatedUserObject.isLogin) {
var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
@ -647,8 +625,7 @@ Future.delayed(Duration(seconds: 0),(){
authService.getDashboard().then((value) => { authService.getDashboard().then((value) => {
setState(() { setState(() {
if (value != null) { if (value != null) {
notificationCount = value['List_PatientDashboard'].isNotEmpty ?? notificationCount = value['List_PatientDashboard'].isNotEmpty ?? value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99
value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'] > 99
? '99+' ? '99+'
: value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); : value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString();
model.setState(model.count, true, notificationCount); model.setState(model.count, true, notificationCount);
@ -665,19 +642,19 @@ Future.delayed(Duration(seconds: 0),(){
} }
if (Platform.isIOS) { if (Platform.isIOS) {
String voipToken = await sharedPref.getString(APNS_TOKEN); String voipToken = await sharedPref.getString(APNS_TOKEN);
getOneSignalVOIPToken(voipToken); // getOneSignalVOIPToken(voipToken);
} }
} }
getOneSignalVOIPToken(String voipToken) { // getOneSignalVOIPToken(String voipToken) {
LiveCareService service = new LiveCareService(); // LiveCareService service = new LiveCareService();
service.getOneSignalVOIPToken(voipToken, context).then((res) { // service.getOneSignalVOIPToken(voipToken, context).then((res) {
print("OneSignalID: $res"); // print("OneSignalID: $res");
AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, res['id']); // AppSharedPreferences().setString(ONESIGNAL_APNS_TOKEN, res['id']);
}).catchError((err) { // }).catchError((err) {
print(err); // print(err);
}); // });
} // }
void showUserConsent() { void showUserConsent() {
sharedPref.setString(IS_COVID_CONSENT_SHOWN, "true"); sharedPref.setString(IS_COVID_CONSENT_SHOWN, "true");

@ -62,7 +62,8 @@ class _SplashScreenState extends State<SplashScreen> {
AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en"); AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en");
var themeNotifier = Provider.of<ThemeNotifier>(context, listen: false); var themeNotifier = Provider.of<ThemeNotifier>(context, listen: false);
themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins')); themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins'));
if (Platform.isIOS) PushNotificationHandler.getInstance().init(context); // Asyncronously // if (Platform.isIOS)
PushNotificationHandler.getInstance().init(context); // Asyncronously
} }
@override @override

@ -19,9 +19,8 @@ import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.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:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it/get_it.dart';
import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_push/huawei_push.dart' as h_push; import 'package:huawei_push/huawei_push.dart' as h_push;
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -30,6 +29,7 @@ import 'app_shared_preferences.dart';
import 'navigation_service.dart'; import 'navigation_service.dart';
// |--> Push Notification Background // |--> Push Notification Background
@pragma('vm:entry-point')
Future<dynamic> backgroundMessageHandler(dynamic message) async { Future<dynamic> backgroundMessageHandler(dynamic message) async {
print("Firebase backgroundMessageHandler!!!"); print("Firebase backgroundMessageHandler!!!");
fir.RemoteMessage message_; fir.RemoteMessage message_;
@ -48,26 +48,14 @@ Future<dynamic> backgroundMessageHandler(dynamic message) async {
notification.createdOn = DateUtil.convertDateToString(DateTime.now()); notification.createdOn = DateUtil.convertDateToString(DateTime.now());
notification.messageTypeData = message.data['picture']; notification.messageTypeData = message.data['picture'];
notification.message = message.data['message']; notification.message = message.data['message'];
await NavigationService.navigateToPage(NotificationsDetailsPage( await NavigationService.navigateToPage(NotificationsDetailsPage(
notification: notification, 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 <--| // Push Notification Background <--|
late AndroidNotificationChannel channel;
RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) { RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) {
final payload_data = jsonDecode(message.data!); final payload_data = jsonDecode(message.data!);
final fire_message = RemoteMessage( final fire_message = RemoteMessage(
@ -118,8 +106,12 @@ _incomingCall(Map<String, dynamic> data) async {
LandingPage.incomingCallData = IncomingCallData.fromJson(data); LandingPage.incomingCallData = IncomingCallData.fromJson(data);
if (LandingPage.isOpenCallPage == false) { if (LandingPage.isOpenCallPage == false) {
LandingPage.isOpenCallPage = true; LandingPage.isOpenCallPage = true;
final permited = await AppPermission.askVideoCallPermission(currentContext!); final bool permited = await AppPermission.askVideoCallPermission(currentContext!);
if (permited) await NavigationService.navigateToPage(IncomingCall(incomingCallData: LandingPage.incomingCallData)); if (permited)
await NavigationService.navigateToPage(
IncomingCall(incomingCallData: LandingPage.incomingCallData),
);
LandingPage.isOpenCallPage = false; LandingPage.isOpenCallPage = false;
} }
await Future.delayed(Duration(milliseconds: 500)); await Future.delayed(Duration(milliseconds: 500));
@ -130,7 +122,6 @@ class PushNotificationHandler {
late BuildContext context; late BuildContext context;
static final PushNotificationHandler _instance = PushNotificationHandler._internal(); static final PushNotificationHandler _instance = PushNotificationHandler._internal();
final voIPKit = FlutterIOSVoIPKit.instance;
late HmsApiAvailability hmsApiAvailability; late HmsApiAvailability hmsApiAvailability;
late Timer timeOutTimer; late Timer timeOutTimer;
@ -162,104 +153,10 @@ class PushNotificationHandler {
static PushNotificationHandler getInstance() => _instance; 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 { init(BuildContext context) async {
this.context = context; 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) { if (Platform.isAndroid) {
try { 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())) { if (!(await Utils.isGoogleServicesAvailable())) {
h_push.Push.enableLogger(); h_push.Push.enableLogger();
final result = await h_push.Push.setAutoInitEnabled(true); final result = await h_push.Push.setAutoInitEnabled(true);
@ -282,7 +179,9 @@ class PushNotificationHandler {
final fcmToken = await FirebaseMessaging.instance.getToken(); final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken != null) onToken(fcmToken); if (fcmToken != null) onToken(fcmToken);
} }
} catch (ex) {} } catch (ex) {
print("Notification Exception: " + ex.toString());
}
} }
if (Platform.isIOS) { if (Platform.isIOS) {
@ -327,19 +226,17 @@ class PushNotificationHandler {
newMessage(message); newMessage(message);
}); });
// FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
print("Push Notification onTokenRefresh: " + fcm_token); print("Push Notification onTokenRefresh: " + fcm_token);
onToken(fcm_token); onToken(fcm_token);
}); });
FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) { // FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String? token) {
print("Push Notification getToken: " + token!); // print("Push Notification getToken: " + token!);
onToken(token!); // onToken(token!);
}); // });
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
} }
newMessage(RemoteMessage remoteMessage) async { 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 { Future<void> requestPermissions() async {
try { try {
if (Platform.isIOS) { if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true); await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
Permission.notification.request(); await Permission.notification.request();
await Permission.camera.request();
await Permission.audio.request();
await Permission.microphone.request();
} }
} catch (_) { } catch (_) {
debugPrint(_.toString()); debugPrint(_.toString());

@ -58,7 +58,7 @@ dependencies:
shared_preferences: ^2.0.0 shared_preferences: ^2.0.0
# flutter_flexible_toast: ^0.1.4 # flutter_flexible_toast: ^0.1.4
fluttertoast: ^8.0.8 fluttertoast: ^8.0.8
firebase_messaging: ^14.7.4 firebase_messaging: 14.1.0
firebase_analytics: ^10.0.5 firebase_analytics: ^10.0.5
# Progress bar # Progress bar
flutter_progress_hud: ^2.0.2 flutter_progress_hud: ^2.0.2
@ -163,7 +163,7 @@ dependencies:
equatable: ^2.0.3 equatable: ^2.0.3
wave: ^0.2.0 wave: ^0.2.0
sms_otp_auto_verify: ^2.1.0 sms_otp_auto_verify: ^2.1.0
flutter_ios_voip_kit: ^0.1.0 #flutter_ios_voip_kit: ^0.1.0
google_api_availability: ^5.0.0 google_api_availability: ^5.0.0
open_filex: ^4.3.2 open_filex: ^4.3.2
path_provider: ^2.0.8 path_provider: ^2.0.8

Loading…
Cancel
Save