diff --git a/android/app/agconnect-services.json b/android/app/agconnect-services.json
index cfdaf83b..91aad2c7 100644
--- a/android/app/agconnect-services.json
+++ b/android/app/agconnect-services.json
@@ -1,6 +1,21 @@
{
+ "agcgw":{
+ "backurl":"connect-drcn.hispace.hicloud.com",
+ "url":"connect-drcn.dbankcloud.cn",
+ "websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com",
+ "websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn"
+ },
+ "agcgw_all":{
+ "CN":"connect-drcn.dbankcloud.cn",
+ "CN_back":"connect-drcn.hispace.hicloud.com",
+ "DE":"connect-dre.dbankcloud.cn",
+ "DE_back":"connect-dre.hispace.hicloud.com",
+ "RU":"connect-drru.dbankcloud.cn",
+ "RU_back":"connect-drru.hispace.hicloud.com",
+ "SG":"connect-dra.dbankcloud.cn",
+ "SG_back":"connect-dra.hispace.hicloud.com"
+ },
"client":{
- "appType":"1",
"cp_id":"2640966000002322881",
"product_id":"736430079244816567",
"client_id":"563735388191982656",
@@ -10,5 +25,50 @@
"api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI",
"package_name":"com.ejada.hmg"
},
- "configuration_version":"1.0"
-}
\ No newline at end of file
+ "oauth_client":{
+ "client_id":"102857389",
+ "client_type":1
+ },
+ "app_info":{
+ "app_id":"102857389",
+ "package_name":"com.ejada.hmg"
+ },
+ "service":{
+ "analytics":{
+ "collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
+ "collector_url_ru":"datacollector-drru.dt.hicloud.com,datacollector-drru.dt.dbankcloud.cn",
+ "collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn",
+ "collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
+ "collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn",
+ "resource_id":"p1",
+ "channel_id":""
+ },
+ "search":{
+ "url":"https://search-drcn.cloud.huawei.com"
+ },
+ "cloudstorage":{
+ "storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn"
+ },
+ "ml":{
+ "mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"
+ }
+ },
+ "region":"CN",
+ "configuration_version":"3.0",
+ "appInfos":[
+ {
+ "package_name":"com.ejada.hmg",
+ "client":{
+ "app_id":"102857389"
+ },
+ "app_info":{
+ "package_name":"com.ejada.hmg",
+ "app_id":"102857389"
+ },
+ "oauth_client":{
+ "client_type":1,
+ "client_id":"102857389"
+ }
+ }
+ ]
+}
diff --git a/android/app/build.gradle b/android/app/build.gradle
index a465569d..65bb55fe 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -67,6 +67,7 @@ android {
}
release {
signingConfig signingConfigs.config
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
staging {
// Specifies a sorted list of fallback build types that the
@@ -77,6 +78,15 @@ android {
matchingFallbacks = ['debug', 'qa', 'release']
}
}
+
+ packagingOptions {
+ exclude 'META-INF/proguard/androidx-annotations.pro'
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
flutter {
@@ -111,6 +121,7 @@ dependencies {
implementation "com.opentok.android:opentok-android-sdk:2.19.1"
+
implementation 'com.facebook.stetho:stetho:1.5.1'
implementation 'com.facebook.stetho:stetho-urlconnection:1.5.1'
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
index 4ace459d..cfab1fd6 100644
--- a/android/app/proguard-rules.pro
+++ b/android/app/proguard-rules.pro
@@ -1,4 +1,27 @@
-keep class tvi.webrtc.** { *; }
-keep class com.twilio.video.** { *; }
-keep class com.twilio.common.** { *; }
--keepattributes InnerClasses
\ No newline at end of file
+-keepattributes InnerClasses
+
+-keep class com.ejada.** { *; }
+-keep class org.webrtc.** { *; }
+
+-ignorewarnings
+-keepattributes *Annotation*
+-keepattributes Exceptions
+-keepattributes InnerClasses
+-keepattributes Signature
+-keep class com.hianalytics.android.**{*;}
+-keep class com.huawei.updatesdk.**{*;}
+-keep class com.huawei.hms.**{*;}
+
+## Flutter wrapper
+-keep class io.flutter.app.** { *; }
+-keep class io.flutter.plugin.** { *; }
+-keep class io.flutter.util.** { *; }
+-keep class io.flutter.view.** { *; }
+-keep class io.flutter.** { *; }
+-keep class io.flutter.plugins.** { *; }
+-dontwarn io.flutter.embedding.**
+-keep class com.huawei.hms.flutter.** { *; }
+-repackageclasses
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index ba03f512..ebc7cc88 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
-
+
@@ -22,24 +22,18 @@
-
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
@@ -48,10 +42,12 @@
+ android:screenOrientation="sensorPortrait"
+ android:label="Dr. Alhabib">
+
+
-
-
+
+
-
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
+ android:name="push_kit_auto_init_enabled"
+ android:value="true" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Push Notification Background
+Future backgroundMessageHandler(dynamic message) async{
+
+ fir.RemoteMessage message_;
+ if(message is h_push.RemoteMessage){ // if huawei remote message convert it to Firebase Remote Message
+ message_ = toFirebaseRemoteMessage(message);
+ }
+
+ if (message_.data != null && message_.data['is_call'] == 'true') {
+ _incomingCall(message_.data);
+ return;
+ }
+
+
+ print("Background message is received, sending local notification.");
+ h_push.Push.localNotification({
+ h_push.HMSLocalNotificationAttr.TITLE: 'Background Message',
+ h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"
+ });
+
+}
+// Push Notification Background <--|
+
+
+
+RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message){
+ final payload_data = jsonDecode(message.data);
+ final fire_message = RemoteMessage(
+ from: message.from,
+ collapseKey: message.collapseKey,
+ data: payload_data['data'],
+ messageId: message.messageId,
+ sentTime: DateTime.fromMillisecondsSinceEpoch(message.sentTime*1000),
+ ttl: message.ttl,
+ category: null,
+ messageType: message.type,
+ notification: RemoteNotification(
+ title: message.notification.title,
+ titleLocArgs: (message.notification.titleLocalizationArgs ?? []).map((e) => e.toString()).toList(),
+ titleLocKey: message.notification.titleLocalizationKey,
+ body: message.notification.body,
+ bodyLocArgs: (message.notification.bodyLocalizationArgs ?? []).map((e) => e.toString()).toList(),
+ bodyLocKey: message.notification.bodyLocalizationKey,
+ android: AndroidNotification(
+ channelId: message.notification.channelId,
+ clickAction: message.notification.clickAction,
+ color: message.notification.color,
+ count: null,
+ imageUrl: message.notification.imageUrl.path,
+ link: message.notification.link.path,
+ smallIcon: message.notification.icon,
+ sound: message.notification.sound,
+ ticker: message.notification.ticker,
+ tag: message.notification.tag,
+ ),
+ )
+ );
+ return fire_message;
+}
+
+_incomingCall(Map 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));
+ LandingPage.isOpenCallPage = false;
+ }
+ await Future.delayed(Duration(milliseconds: 500));
+ await AppSharedPreferences().remove('call_data');
+}
+
+class PushNotificationHandler{
+ final BuildContext context;
+ static PushNotificationHandler _instance;
+
+ PushNotificationHandler(this.context){
+ PushNotificationHandler._instance = this;
+ }
+
+ static PushNotificationHandler getInstance() => _instance;
+
+ init() async{
+ if (Platform.isIOS) {
+ final permission = await FirebaseMessaging.instance.requestPermission();
+ if(permission.authorizationStatus == AuthorizationStatus.denied)
+ return;
+ }
+
+ if(Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) { // 'Android HMS' (Handle Huawei Push_Kit Streams)
+
+ h_push.Push.enableLogger();
+ final result = await h_push.Push.setAutoInitEnabled(true);
+
+ h_push.Push.onNotificationOpenedApp.listen((message){
+ newMessage(toFirebaseRemoteMessage(message));
+ }, onError: (e) => print(e.toString()));
+
+ h_push.Push.onMessageReceivedStream.listen((message){
+ newMessage(toFirebaseRemoteMessage(message));
+ }, onError: (e) => print(e.toString()));
+
+
+ h_push.Push.getTokenStream.listen((token){
+ onToken(token);
+ }, onError: (e) => print(e.toString()));
+ await h_push.Push.getToken('');
+
+
+ h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler);
+
+ }else{ // 'Android GMS or iOS' (Handle Firebase Messaging Streams)
+
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
+ newMessage(message);
+ });
+
+ FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
+ newMessage(message);
+ });
+
+ FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
+ onToken(fcm_token);
+ });
+
+ FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
+
+ final fcmToken = await FirebaseMessaging.instance.getToken();
+ if(fcmToken != null)
+ onToken(fcmToken);
+ }
+ }
+
+
+ newMessage(RemoteMessage remoteMessage){
+ print('RemoteMessage.data:: ${remoteMessage.data}');
+ if(remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true)
+ _incomingCall(remoteMessage.data);
+
+ }
+
+ onToken(String token) async{
+ print("Push Notification Token: " + token);
+ AppSharedPreferences().setString(PUSH_TOKEN, token);
+ DEVICE_TOKEN = token;
+ }
+
+ onResume() async {
+ var call_data = await AppSharedPreferences().getObject('call_data');
+ if(call_data != null){
+ _incomingCall(call_data);
+ }
+ }
+
+}
+
+/* todo verify all functionality */
+// _firebaseMessaging.configure(
+// // onMessage: (Map message) async {
+// // // showDialog("onMessage: $message");
+// // print("onMessage: $message");
+// // print(message);
+// // print(message['name']);
+// // print(message['appointmentdate']);
+// //
+// // if (Platform.isIOS) {
+// // if (message['is_call'] == "true") {
+// // var route = ModalRoute.of(context);
+// //
+// // if (route != null) {
+// // print(route.settings.name);
+// // }
+// //s
+// // Map myMap = new Map.from(mesage);
+// // print(myMap);
+// // LandingPage.isOpenCallPage = true;
+// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
+// // if (!isPageNavigated) {
+// // isPageNavigated = true;
+// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
+// // isPageNavigated = false;
+// // });
+// // }
+// // } else {
+// // print("Is Call Not Found iOS");
+// // }
+// // } else {
+// // print("Is Call Not Found iOS");
+// // }
+// //
+// // if (Platform.isAndroid) {
+// // if (message['data'].containsKey("is_call")) {
+// // var route = ModalRoute.of(context);
+// //
+// // if (route != null) {
+// // print(route.settings.name);
+// // }
+// //
+// // Map myMap = new Map.from(message['data']);
+// // print(myMap);
+// // if (LandingPage.isOpenCallPage) {
+// // return;
+// // }
+// // LandingPage.isOpenCallPage = true;
+// // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
+// // if (!isPageNavigated) {
+// // isPageNavigated = true;
+// // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
+// // Future.delayed(Duration(seconds: 5), () {
+// // isPageNavigated = false;
+// // });
+// // });
+// // }
+// // } else {
+// // print("Is Call Not Found Android");
+// // LocalNotification.getInstance().showNow(title: message['notification']['title'], subtitle: message['notification']['body']);
+// // }
+// // } else {
+// // print("Is Call Not Found Android");
+// // }
+// // },
+// onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
+// onLaunch: (Map message) async {
+// print("onLaunch: $message");
+// // showDialog("onLaunch: $message");
+// },
+// onResume: (Map message) async {
+// print("onResume: $message");
+// print(message);
+// print(message['name']);
+// print(message['appointmentdate']);
+//
+// // showDialog("onResume: $message");
+//
+// if (Platform.isIOS) {
+// if (message['is_call'] == "true") {
+// var route = ModalRoute.of(context);
+//
+// if (route != null) {
+// print(route.settings.name);
+// }
+//
+// Map myMap = new Map.from(message);
+// print(myMap);
+// LandingPage.isOpenCallPage = true;
+// LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
+// if (!isPageNavigated) {
+// isPageNavigated = true;
+// Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
+// isPageNavigated = false;
+// });
+// }
+// } else {
+// print("Is Call Not Found iOS");
+// }
+// } else {
+// print("Is Call Not Found iOS");
+// }
+// },
+// );
\ No newline at end of file
diff --git a/pubspec.yaml b/pubspec.yaml
index ef1b799f..a7996dc8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -57,6 +57,8 @@ dependencies:
fluttertoast: ^8.0.8
firebase_messaging: ^11.1.0
firebase_analytics: ^8.3.4
+
+
# Progress bar
progress_hud_v2: ^2.0.0
percent_indicator: ^3.4.0
@@ -85,7 +87,10 @@ dependencies:
charts_flutter: ^0.12.0
google_maps_flutter: ^2.1.1
+
+ # Huawei
huawei_map: ^6.0.1+304
+ huawei_push: ^5.3.0+304
# Qr code Scanner TODO fix it
# barcode_scanner: ^1.0.1