Wd: Incoming page and notification added to the application.

* changed the firebase package.
    * added flutter_callkit_incoming
    * added android.permission.FOREGROUND_SERVICE_PHONE_CALL
    * saved the caller object inside the shared preference for the routing
    * changed the incoming call function.
dev_v3.13.6_livecare
Syed Taha Alam 4 months ago
parent c1dae542c9
commit 5c75a186ed

@ -31,8 +31,7 @@
android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL"
tools:node="remove" />
android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"
tools:node="remove" />
@ -84,6 +83,10 @@
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-feature
android:name="android.hardware.location.network"
@ -97,6 +100,8 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_PHONE_CALL" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<!-- Detect Reboot Permission -->
<!-- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> -->
<queries>

@ -151,8 +151,13 @@ import 'services/pharmacy_services/product_detail_service.dart';
GetIt locator = GetIt.instance;
void setupNavigator(){
locator.registerSingleton( NavigationService());
}
///di
void setupLocator() {
setupNavigator();
/// Others
locator.registerLazySingleton(() => FlutterLocalNotificationsPlugin());
@ -168,7 +173,6 @@ void setupLocator() {
locator.registerLazySingleton(() => InsuranceCardService());
locator.registerLazySingleton(() => VitalSignService());
locator.registerLazySingleton(() => MedicalService());
locator.registerLazySingleton(() => NavigationService());
locator.registerLazySingleton(() => ReportsService());
locator.registerLazySingleton(() => DashboardService());
locator.registerLazySingleton(() => AppointmentRateService());

@ -6,6 +6,10 @@ import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/viewModels/PharmacyPagesViewModel.dart';
import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart';
import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/platform_exception_alert_dialog.dart';
import 'package:diplomaticquarterapp/pages/conference/zoom/call_screen.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/payfort_services/payfort_view_model.dart';
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
@ -14,6 +18,7 @@ import 'package:diplomaticquarterapp/theme/theme_notifier.dart';
import 'package:diplomaticquarterapp/theme/theme_value.dart';
import 'package:diplomaticquarterapp/uitl/DeepLinkHandler.dart';
import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:firebase_core/firebase_core.dart';
@ -25,6 +30,7 @@ import 'config/size_config.dart';
import 'core/viewModels/pharmacyModule/OrderPreviewViewModel.dart';
import 'core/viewModels/project_view_model.dart';
import 'locator.dart';
import 'models/LiveCare/IncomingCallData.dart';
import 'pages/pharmacies/compare-list.dart';
void main() async {
@ -102,13 +108,67 @@ class _MyApp extends State<MyApp> {
super.dispose();
}
late final AppLifecycleListener _listener;
Future<void> initDeepLinks() async {
// Handle links
_linkSubscription = AppLinks().uriLinkStream.listen((uri) {
debugPrint('onAppLink: $uri');
openAppLink(uri);
});
_listener = AppLifecycleListener(
onShow: () => {},
onResume: () =>{},
onHide: () => {},
onInactive: () => {},
onPause: () => {},
onDetach: () => {},
onRestart: () => {},
onStateChange: (state) async {
if(state == AppLifecycleState.resumed) {
await Future.delayed(Duration(seconds: 5));
_handleTransition();
}
},
);
_handleTransition(shouldApplyDelay: true);
}
void _handleTransition({bool shouldApplyDelay = false}) async {
var data = await AppSharedPreferences().getObject('call_data');
if(data == null) return;
await AppSharedPreferences().remove('call_data');
if(shouldApplyDelay)
await Future.delayed(Duration(seconds: 5));
var incomingcallData= IncomingCallData.fromJson(data);
openCallPage(incomingcallData);
}
Future<void> openCallPage(IncomingCallData incomingCallData) async {
try {
LandingPage.isOpenCallPage = false;
if (incomingCallData!.background == "0") {
// Zoom Call Page
// Navigator.of(context).pop();
Navigator.pushNamed(
locator<NavigationService>().navigatorKey.currentContext!,
"zoom_call_page",
arguments: CallArguments(incomingCallData!.sessionId!, "123", "Patient", "40", "0", false, int.parse(incomingCallData!.appointmentNo!)),
);
} else {
// OpenTok Call Page
await Navigator.of(locator<NavigationService>().navigatorKey.currentContext!).push(
MaterialPageRoute(
builder: (BuildContext context) {
return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: incomingCallData!.sessionId!, token: incomingCallData!.token!);
},
),
);
}
} catch (err) {
print(err);
await PlatformExceptionAlertDialog(
exception: Exception(err),
).show(context);
}
}
void openAppLink(Uri uri) {

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
@ -37,6 +38,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
import 'package:diplomaticquarterapp/widgets/others/not_auh_page.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
// import 'package:flutter_app_icon_badge/flutter_app_icon_badge.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -647,6 +649,15 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
void checkUserStatus(token) async {
await PushNotificationHandler.getInstance().requestPermissions();
if (Platform.isAndroid) {
final deviceInfo = DeviceInfoPlugin();
final androidInfo = await deviceInfo.androidInfo;
int sdkInt = androidInfo.version.sdkInt ?? 0;
if(sdkInt>= 33){
await FlutterCallkitIncoming.requestFullIntentPermission();
}
}
// authService.selectDeviceImei(token).then((SelectDeviceIMEIRES? value) => setUserValues(value));
if (authenticatedUserObject.isLogin) {
var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));

@ -81,9 +81,11 @@ class _SplashScreenState extends State<SplashScreen> {
projectProvider.setProjectsDetailList(_privilegeService.projectDetailListModel);
double lat = await AppSharedPreferences().getDouble(USER_LAT) ?? 0.0;
double long = await AppSharedPreferences().getDouble(USER_LONG) ?? 0.0;
var callData = await AppSharedPreferences().getObject('call_data');
AppSharedPreferences().clear(); // Clearing Shared Preferences On App Launch
await AppSharedPreferences().setDouble(USER_LAT, lat);
await AppSharedPreferences().setDouble(USER_LONG, long);
await AppSharedPreferences().setObject('call_data', callData);
AppSharedPreferences().setString(APP_LANGUAGE, projectProvider.isArabic ? "ar" : "en");
var themeNotifier = Provider.of<ThemeNotifier>(context, listen: false);
themeNotifier.setTheme(defaultTheme(fontName: projectProvider.isArabic ? 'Cairo' : 'Poppins'));

@ -1,7 +1,8 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter_callkit_incoming/entities/call_event.dart';
import 'package:uuid/uuid.dart';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart';
@ -22,6 +23,12 @@ 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_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';
import 'package:flutter_incoming_call/flutter_incoming_call.dart';
// import 'package:flutter_ios_voip_kit/call_state_type.dart';
// import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart';
@ -31,6 +38,7 @@ import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_push/huawei_push.dart' as h_push;
import 'package:permission_handler/permission_handler.dart';
import '../pages/conference/widgets/platform_exception_alert_dialog.dart';
import 'app_shared_preferences.dart';
import 'navigation_service.dart';
@ -44,7 +52,6 @@ Future<dynamic> backgroundMessageHandler(dynamic message) async {
message_ = toFirebaseRemoteMessage(message);
h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"});
}
if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) {
// showCallkitIncoming(message);
_incomingCall(message.data);
@ -162,18 +169,159 @@ callPage(String sessionID, String token) async {
_incomingCall(Map<String, dynamic> data) async {
LandingPage.incomingCallData = IncomingCallData.fromJson(data);
var dataItem = await AppSharedPreferences().getObject('call_data');
if(dataItem != null ) return; // to stop repeated attempt to invoke the call
if (LandingPage.isOpenCallPage == false) {
LandingPage.isOpenCallPage = true;
final bool permited = await AppPermission.askVideoCallPermission(currentContext!);
if (permited)
await NavigationService.navigateToPage(
IncomingCall(incomingCallData: LandingPage.incomingCallData),
);
WidgetsFlutterBinding.ensureInitialized();
var _currentUuid = Uuid().v4();
CallKitParams callKitParams = CallKitParams(
id: _currentUuid,
nameCaller: "${LandingPage.incomingCallData.doctorname}"
"\n Dr Sulaiman Al Habib \n ${LandingPage.incomingCallData.clinicname}",
appName: 'Dr Sulaiman Al Habib',
avatar: '',
handle: LandingPage.incomingCallData.name,
type: 0,
textAccept: 'Accept',
textDecline: 'Decline',
missedCallNotification: NotificationParams(
showNotification: true,
isShowCallback: false,
subtitle: 'Missed call',
callbackText: '',
),
callingNotification: const NotificationParams(
showNotification: true,
isShowCallback: true,
subtitle: 'Calling...',
callbackText: 'Hang Up',
),
duration: 30000,
extra: <String, dynamic>{'userId': '1a2b3c4d'},
headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
android: const AndroidParams(
isCustomNotification: true,
isShowLogo: false,
logoUrl: '',
ringtonePath: 'system_ringtone_default',
backgroundColor: '#D02127',
backgroundUrl: '',
actionColor: '#4CAF50',
textColor: '#ffffff',
incomingCallNotificationChannelName: "Incoming Call",
missedCallNotificationChannelName: "Missed Call",
isShowCallID: false
),
ios: IOSParams(
iconName: 'Dr Sulaiman Al Habib',
handleType: 'generic',
supportsVideo: true,
maximumCallGroups: 2,
maximumCallsPerCallGroup: 1,
audioSessionMode: 'default',
audioSessionActive: true,
audioSessionPreferredSampleRate: 44100.0,
audioSessionPreferredIOBufferDuration: 0.005,
supportsDTMF: true,
supportsHolding: true,
supportsGrouping: false,
supportsUngrouping: false,
ringtonePath: 'system_ringtone_default',
),
);
await FlutterCallkitIncoming.showCallkitIncoming(callKitParams);
try {
FlutterCallkitIncoming.onEvent.listen((event) async {
switch (event!.event) {
case Event.actionCallIncoming:
break;
case Event.actionCallStart:
break;
case Event.actionCallAccept:
await FlutterCallkitIncoming.endAllCalls();
try {
openCallPage(LandingPage.incomingCallData,
locator<NavigationService>().navigatorKey
.currentContext!);
} catch (e) {
await AppSharedPreferences().setObject('call_data', data);
var data1 = await AppSharedPreferences().getObject('call_data');
}
break;
case Event.actionCallDecline:
break;
case Event.actionCallEnded:
break;
case Event.actionCallTimeout:
break;
case Event.actionCallCallback:
break;
case Event.actionCallToggleHold:
break;
case Event.actionCallToggleMute:
break;
case Event.actionCallToggleDmtf:
break;
case Event.actionCallToggleGroup:
break;
case Event.actionCallToggleAudioSession:
break;
case Event.actionDidUpdateDevicePushTokenVoip:
break;
case Event.actionCallCustom:
break;
}
});
} on Exception catch (e) {
print(e);
}
}
LandingPage.isOpenCallPage = false;
await Future.delayed(Duration(milliseconds: 500));
}
Future<void> openCallPage(IncomingCallData incomingCallData, BuildContext context) async {
try {
LandingPage.isOpenCallPage = false;
if (incomingCallData!.background == "0") {
// Zoom Call Page
// Navigator.of(context).pop();
Navigator.pushReplacementNamed(
context,
"zoom_call_page",
arguments: CallArguments(incomingCallData!.sessionId!, "123", "Patient", "40", "0", false, int.parse(incomingCallData!.appointmentNo!)),
);
} else {
// OpenTok Call Page
await Navigator.of(context).pushReplacement(
MaterialPageRoute(
// fullscreenDialog: true,
builder: (BuildContext context) {
// final caller = widget.incomingCallData.callerID;
// final receiver = widget.incomingCallData.receiverID;
// final host = widget.incomingCallData.server;
// if(widget.incomingCallData.isWebRTC == "true"){
// return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host);
// }else{
return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: incomingCallData!.sessionId!, token: incomingCallData!.token!);
},
),
);
}
} catch (err) {
print(err);
await PlatformExceptionAlertDialog(
exception: Exception(err),
).show(context);
}
await Future.delayed(Duration(milliseconds: 500));
await AppSharedPreferences().remove('call_data');
}
class PushNotificationHandler {
@ -382,7 +530,6 @@ class PushNotificationHandler {
// });
// }
FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
}
newMessage(RemoteMessage remoteMessage) async {
@ -440,10 +587,6 @@ class PushNotificationHandler {
}
onResume() async {
var call_data = await AppSharedPreferences().getObject('call_data');
if (call_data != null) {
_incomingCall(call_data);
}
}
Future<void> requestPermissions() async {

@ -66,7 +66,7 @@ dependencies:
shared_preferences: ^2.0.0
# flutter_flexible_toast: ^0.1.4
fluttertoast: ^8.0.8
firebase_messaging: 14.1.0
firebase_messaging: 14.7.7
firebase_analytics: ^10.0.5
# Progress bar
flutter_progress_hud: ^2.0.2
@ -75,6 +75,7 @@ dependencies:
# Icons
font_awesome_flutter: any
cupertino_icons: ^1.0.0
flutter_callkit_incoming: ^2.5.3-alpha
# Image Attachments
image_picker: ^1.0.4
@ -88,6 +89,7 @@ dependencies:
# UI Reqs
expandable: ^5.0.1
uuid: ^3.0.7
# charts
flutter_charts: ^0.5.2

Loading…
Cancel
Save