From f20929b1dcfd6ba77ee65e7065a4e226bcfc5140 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Sun, 6 Oct 2024 18:14:28 +0300 Subject: [PATCH] huawei integration added & code compatibility issues fix. --- android/app/agconnect-services.json | 57 ++++++++++++++ android/app/build.gradle | 21 +++-- android/app/proguard-rules.pro | 11 +++ android/app/src/main/AndroidManifest.xml | 23 ++++++ .../java/com/example/test_sa/HService.java | 25 ++++++ android/build.gradle | 48 ++++++++---- android/gradle.properties | 2 +- android/settings.gradle | 2 +- .../firebase_notification_manger.dart | 78 +++++++++++++++++-- lib/models/ppm/ppm_check_list.dart | 12 +++ lib/models/user.dart | 10 +-- lib/new_views/pages/login_page.dart | 7 ++ .../pentry/pentry_ppm_check_list_form.dart | 2 +- pubspec.lock | 32 ++++++++ pubspec.yaml | 6 +- 15 files changed, 293 insertions(+), 43 deletions(-) create mode 100644 android/app/agconnect-services.json create mode 100644 android/app/src/main/java/com/example/test_sa/HService.java diff --git a/android/app/agconnect-services.json b/android/app/agconnect-services.json new file mode 100644 index 00000000..9c3955cc --- /dev/null +++ b/android/app/agconnect-services.json @@ -0,0 +1,57 @@ +{ + "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.hispace.dbankcloud.ru", + "RU_back":"connect-drru.hispace.dbankcloud.cn", + "SG":"connect-dra.dbankcloud.cn", + "SG_back":"connect-dra.hispace.hicloud.com" + }, + "websocketgw_all":{ + "CN":"connect-ws-drcn.hispace.dbankcloud.cn", + "CN_back":"connect-ws-drcn.hispace.dbankcloud.com", + "DE":"connect-ws-dre.hispace.dbankcloud.cn", + "DE_back":"connect-ws-dre.hispace.dbankcloud.com", + "RU":"connect-ws-drru.hispace.dbankcloud.ru", + "RU_back":"connect-ws-drru.hispace.dbankcloud.cn", + "SG":"connect-ws-dra.hispace.dbankcloud.cn", + "SG_back":"connect-ws-dra.hispace.dbankcloud.com" + }, + "client":{ + "cp_id":"2640966000002322881", + "product_id":"388421841222408054", + "client_id":"1492841575221308864", + "client_secret":"9F5ABC6C041C90D9CFC2DB4B032E224026C566D30147D22CC25789DAFF393B14", + "project_id":"388421841222408054", + "app_id":"111820283", + "api_key":"DQEDACmCXaRhehJz6Col9ZoLjfEmJCZn2/FIsIDJccmzQmq61gFYr7msISoMMgprtwaxo5vZ4Gyn2TIj6Y7v+sd1IGqforIJaKyaPA==", + "package_name":"com.hmg.atoms" + }, + "oauth_client":{ + "client_id":"111820283", + "client_type":1 + }, + "app_info":{ + "app_id":"111820283", + "package_name":"com.hmg.atoms" + }, + "configuration_version":"3.0", + "appInfos":[ + { + "package_name":"com.hmg.atoms", + "client":{ + "app_id":"111820283" + }, + "app_info":{ + "package_name":"com.hmg.atoms", + "app_id":"111820283" + }, + "oauth_client":{ + "client_type":1, + "client_id":"111820283" + } + } + ] +} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 7d86fe74..5ad2b550 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -13,11 +13,6 @@ if (localPropertiesFile.exists()) { } } -//def flutterRoot = localProperties.getProperty('flutter.sdk') -//if (flutterRoot == null) { -// throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -//} - def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' @@ -28,17 +23,13 @@ if (flutterVersionName == null) { flutterVersionName = '1.0' } -//apply plugin: 'com.android.application' -//apply plugin: 'kotlin-android' -//apply plugin: 'com.google.gms.google-services' -//apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } +apply plugin: "com.huawei.agconnect" android { compileSdkVersion 34 @@ -56,8 +47,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion 21 targetSdkVersion 34 - versionCode 9 - versionName '1.2.2' + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName } signingConfigs { @@ -86,3 +77,9 @@ android { flutter { source '../..' } + +dependencies { + implementation 'com.huawei.agconnect:agconnect-core:1.5.2.300' + implementation 'com.huawei.hms:push:6.7.0.300' +} + diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro index 6f22e90b..27acb9d8 100644 --- a/android/app/proguard-rules.pro +++ b/android/app/proguard-rules.pro @@ -17,6 +17,17 @@ -keep class * implements com.google.gson.JsonSerializer -keep class * implements com.google.gson.JsonDeserializer +-ignorewarnings +-keepattributes *Annotation* +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes Signature +-keepattributes SourceFile,LineNumberTable +-keep class com.huawei.hianalytics.**{*;} +-keep class com.huawei.updatesdk.**{*;} +-keep class com.huawei.hms.**{*;} +-keep class com.huawei.hms.flutter.** { *; } + # Prevent R8 from leaving Data object members always null -keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName ; diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c1ce832f..cc073daf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -68,5 +68,28 @@ + + + + + + + + + + + + + + diff --git a/android/app/src/main/java/com/example/test_sa/HService.java b/android/app/src/main/java/com/example/test_sa/HService.java new file mode 100644 index 00000000..6ff86bab --- /dev/null +++ b/android/app/src/main/java/com/example/test_sa/HService.java @@ -0,0 +1,25 @@ +package com.example.test_sa; + +import android.util.Log; + +import com.huawei.hms.push.HmsMessageService; +import com.huawei.hms.push.RemoteMessage; + +public class HService extends HmsMessageService { + + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + super.onMessageReceived(remoteMessage); + + if (remoteMessage != null) { + System.out.println("remote:"+remoteMessage.getData()); + if (!remoteMessage.getData().isEmpty()) { + Log.d("HMS", "Payload" + remoteMessage.getData()); + } + + if (remoteMessage.getNotification() != null) { + Log.d("HMS", "Message Notification Body: " + remoteMessage.getNotification().getBody()); + } + } + } +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index f98890b1..dd29c274 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,32 +1,52 @@ -//buildscript { -// ext.kotlin_version = '1.8.20' -// repositories { -// google() -// mavenCentral() -// } -// -// dependencies { -// classpath 'com.android.tools.build:gradle:7.1.2' -// classpath 'com.google.gms:google-services:4.3.13' -// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" -// } -//} +buildscript { + ext.kotlin_version = '1.9.25' + repositories { + google() + mavenCentral() + maven {url 'https://developer.huawei.com/repo/'} + } + dependencies { + classpath "com.android.tools.build:gradle:7.1.2" + classpath 'com.huawei.agconnect:agcp:1.5.2.300' + } +} +configurations.all { + resolutionStrategy.force 'androidx.appcompat:appcompat:1.3.0' +} allprojects { repositories { google() mavenCentral() + maven {url 'https://developer.huawei.com/repo/'} } } rootProject.buildDir = '../build' + subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" + afterEvaluate { project -> + if (project.plugins.hasPlugin("com.android.application") || + project.plugins.hasPlugin("com.android.library")) { + project.android { + compileSdkVersion 34 + } + } + } } subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(':app') } + +//subprojects { +// project.buildDir = "${rootProject.buildDir}/${project.name}" +//} +//subprojects { +// project.evaluationDependsOn(':app') +//} + tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/android/gradle.properties b/android/gradle.properties index 94adc3a3..ff5389fd 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx2048m android.useAndroidX=true android.enableJetifier=true diff --git a/android/settings.gradle b/android/settings.gradle index 5339b725..9f6599b7 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -32,7 +32,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.1.2" apply false // Replace {agpVersion} with your version, e.g., "7.3.0" - id "org.jetbrains.kotlin.android" version "1.8.20" apply false // Replace {kotlinVersion} with your version, e.g., "1.7.10" + id "org.jetbrains.kotlin.android" version "1.9.25" apply false // Replace {kotlinVersion} with your version, e.g., "1.7.10" id "com.google.gms.google-services" version "4.3.13" apply false // Replace {kotlinVersion} with your version, e.g., "1.7.10" } diff --git a/lib/controllers/notification/firebase_notification_manger.dart b/lib/controllers/notification/firebase_notification_manger.dart index d2833de6..1b47cafc 100644 --- a/lib/controllers/notification/firebase_notification_manger.dart +++ b/lib/controllers/notification/firebase_notification_manger.dart @@ -3,10 +3,12 @@ import 'dart:io'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; +import 'package:google_api_availability/google_api_availability.dart'; import 'package:test_sa/controllers/notification/notification_manger.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/device/asset_transfer.dart'; import 'package:test_sa/models/new_models/gas_refill_model.dart'; +import 'package:huawei_push/huawei_push.dart' as h_push; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/views/pages/device_transfer/device_transfer_details.dart'; import 'package:test_sa/views/pages/user/gas_refill/gas_refill_details.dart'; @@ -20,16 +22,59 @@ class FirebaseNotificationManger { static FirebaseMessaging messaging = FirebaseMessaging.instance; static String? token; - static Future getToken() async { + static Future getToken() async { NotificationSettings settings = await messaging.requestPermission(alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true); - if (settings.authorizationStatus == AuthorizationStatus.authorized) { + if (Platform.isAndroid) { try { - token = await messaging.getToken(); - } catch (ex) {} + if (!(await isGoogleServicesAvailable())) { + h_push.Push.enableLogger(); + final result = await h_push.Push.setAutoInitEnabled(true); + h_push.Push.onMessageReceivedStream.listen(_onMessageReceived, onError: _onMessageReceiveError); + + h_push.Push.getTokenStream.listen((hToken) { + // onToken(token); + print("Huawei Token: ${hToken}"); + token = hToken; + }, onError: (e) { + print( "Huawei TokenError"+e.toString()); + }); + h_push.Push.getToken(''); + } else { + if (settings.authorizationStatus == AuthorizationStatus.authorized) { + try { + token = await messaging.getToken(); + } catch (ex) {} + } + } + } catch (ex) { + print("Notification Exception: " + ex.toString()); + } + } else { + if (settings.authorizationStatus == AuthorizationStatus.authorized) { + try { + token = await messaging.getToken(); + } catch (ex) {} + } } print("pushToken:$token"); - return token!; + } + + static void _onMessageReceived(h_push.RemoteMessage remoteMessage) { + print("onMessageReceivedStream:${remoteMessage.toMap()}"); + } + + static void _onMessageReceiveError(Object error) { + print("onMessageReceivedStream:${error?.toString()}"); + } + + static Future isGoogleServicesAvailable() async { + GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability(); + String status = availability.toString().split('.').last; + if (status == "success") { + return true; + } + return false; } static void handleMessage(context, Map messageData) { @@ -64,7 +109,28 @@ class FirebaseNotificationManger { } static initialized(BuildContext context) async { - //await Firebase.initializeApp(); + + if (!(await isGoogleServicesAvailable())) { + var initialNotification = await h_push.Push.getInitialNotification(); + if (initialNotification != null) { + Map remoteData = Map.from(initialNotification["extras"] as Map); + handleMessage(context, remoteData); + } + + h_push.Push.onNotificationOpenedApp.listen((message) { + try { + if (message is Map) { + Map remoteData = message; + remoteData = remoteData["extras"]; + handleMessage(context, remoteData); + } + } catch (ex) { + print("parsingError:$ex"); + } + }, onError: (e) => print("onNotificationOpenedApp Error${e.toString()}")); + return; + } + NotificationSettings settings; try { diff --git a/lib/models/ppm/ppm_check_list.dart b/lib/models/ppm/ppm_check_list.dart index 84712fe0..af2d35b1 100644 --- a/lib/models/ppm/ppm_check_list.dart +++ b/lib/models/ppm/ppm_check_list.dart @@ -7,6 +7,8 @@ class PpmChecklists { this.taskComment, this.measuredValue, this.taskStatusName, + this.instructionTextId, + this.text, }); PpmChecklists.fromJson(dynamic json) { @@ -17,6 +19,8 @@ class PpmChecklists { taskStatusName = json['taskStatusName']; taskComment = json['taskComment']; measuredValue = json['measuredValue']; + instructionTextId = json['instructionTextId']; + text = json['text']; } num? id; @@ -26,6 +30,8 @@ class PpmChecklists { String? taskComment; String? measuredValue; String? taskStatusName; + num? instructionTextId; + String? text; PpmChecklists copyWith({ num? id, @@ -35,6 +41,8 @@ class PpmChecklists { String? taskComment, String? measuredValue, String? taskStatusName, + num? instructionTextId, + String? text, }) => PpmChecklists( id: id ?? this.id, @@ -44,6 +52,8 @@ class PpmChecklists { taskComment: taskComment ?? this.taskComment, measuredValue: measuredValue ?? this.measuredValue, taskStatusName: taskStatusName ?? this.taskStatusName, + instructionTextId: instructionTextId ?? this.instructionTextId, + text: text ?? this.text, ); Map toJson() { @@ -55,6 +65,8 @@ class PpmChecklists { map['taskComment'] = taskComment; map['measuredValue'] = measuredValue; map['taskStatusName'] = taskStatusName; + map['instructionTextId'] = instructionTextId; + map['text'] = text; return map; } } diff --git a/lib/models/user.dart b/lib/models/user.dart index 6a8a7dd1..40e95b58 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; import 'package:test_sa/models/enums/user_types.dart'; @@ -71,12 +73,8 @@ class User { bool get isLiveToken => tokenlife != null && (DateTime.tryParse(tokenlife!)?.isAfter(DateTime.now()) ?? false); Future> toLoginJson() async { - if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); - return { - "username": userName, - "password": password, - "fireBaseToken": FirebaseNotificationManger.token ?? "", - }; + String notificationType = (Platform.isAndroid && !(await FirebaseNotificationManger.isGoogleServicesAvailable())) ? "HMC" : "FCM"; + return {"username": userName, "password": password, "fireBaseToken": FirebaseNotificationManger?.token ?? "", "notificationType": notificationType}; } UsersTypes? get type { diff --git a/lib/new_views/pages/login_page.dart b/lib/new_views/pages/login_page.dart index 892baf1c..2e069ffa 100644 --- a/lib/new_views/pages/login_page.dart +++ b/lib/new_views/pages/login_page.dart @@ -143,6 +143,7 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:test_sa/app_strings/app_asset.dart'; +import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; import 'package:test_sa/controllers/providers/settings/app_settings.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; @@ -175,6 +176,12 @@ class _LoginPageState extends State { bool rememberMe = false; + @override + void initState() { + super.initState(); + if (FirebaseNotificationManger.token == null) FirebaseNotificationManger.getToken(); + } + @override Widget build(BuildContext context) { _userProvider = Provider.of(context); diff --git a/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart b/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart index 01cbbd3c..c3155494 100644 --- a/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart +++ b/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart @@ -36,7 +36,7 @@ class _PentryPMChecklistFormState extends State { return Card( child: ExpansionTile( shape: const Border(), - title: (list![index].task ?? "").heading5(context), + title: (list![index].instructionTextId == null ? (list[index].task ?? "") : (list[index].text ?? "")).heading5(context), onExpansionChanged: (value) { if (!value) { showLabel.remove(index); diff --git a/pubspec.lock b/pubspec.lock index b3c7293d..530a0f50 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -557,6 +557,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.6.6" + google_api_availability: + dependency: "direct main" + description: + name: google_api_availability + sha256: "3e9548cfd991d983d11425a2436d5bd957d048c279cc9e145ffe3f36fd847385" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + google_api_availability_android: + dependency: transitive + description: + name: google_api_availability_android + sha256: d95429ae78083585c312de2c6578085e7d53d100a94656d691bce0bb0ce435be + url: "https://pub.dev" + source: hosted + version: "1.0.1" + google_api_availability_platform_interface: + dependency: transitive + description: + name: google_api_availability_platform_interface + sha256: "65b7da62fe5b582bb3d508628ad827d36d890710ea274766a992a56fa5420da6" + url: "https://pub.dev" + source: hosted + version: "1.0.1" graphs: dependency: transitive description: @@ -581,6 +605,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + huawei_push: + dependency: "direct main" + description: + name: huawei_push + sha256: "94c70987591442e301745e881ee2768ca5349800294bb7bdd46f9f80d1096c53" + url: "https://pub.dev" + source: hosted + version: "6.12.0+302" image: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d9ec191f..66cfa7ee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.2.2+9 +version: 1.2.3+10 environment: sdk: ">=3.5.0 <4.0.0" @@ -56,7 +56,7 @@ dependencies: firebase_core: ^3.4.1 firebase_messaging: ^15.1.1 qr_code_scanner: ^1.0.1 - flutter_sound: ^9.2.13 + flutter_sound: ^9.3.1 permission_handler: ^11.3.1 rive: ^0.13.13 another_flushbar: @@ -82,6 +82,8 @@ dependencies: flutter_custom_month_picker: ^0.1.3 syncfusion_flutter_charts: ^26.2.14 local_auth: ^2.3.0 + google_api_availability: ^5.0.0 + huawei_push: ^6.5.0+300 local_auth_darwin: any dev_dependencies: