Integrating Huawei Analytics Kit to Flutter Projects and Sending Events - Huawei Developers

More information like this, you can visit HUAWEI Developer Forum​
Hello everyone,
In this article, I am going to create a Flutter project –actually a tiny game- and explain how to implement Analytics Kit. But first, let me inform you about Huawei Analytics Kit a little.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Huawei Analytics Kit
Huawei Analytics Kit offers you a range of analytics models that help you not only to analyze users’ behavior with preset and custom events, but also gain an insight into your products and contents. So that you can improve your skills about marketing your apps and optimizing your products.
HUAWEI Analytics Kit identifies users and collects statistics on users by anonymous application identifier (AAID). The AAID is reset in the following scenarios:
1) Uninstall or reinstall the app.
2) The user clears the app data.
After the AAID is reset, the user will be counted as a new user.
HUAWEI Analytics Kit supports event management. For each event, maximum 25 parameters; for each app maximum 100 parameters can be defined.
There are 3 types of events: Automatically collected, predefined and custom.
Automatically collected events are collected from the moment you enable the kit in your code. Event IDs are already reserved by HUAWEI Analytics Kit and cannot be reused.
Predefined events include their own Event IDs which are predefined by the HMS Core Analytics SDK based on common application scenarios. The ID of a custom event cannot be the same as a predefined event’s ID. If so, you will create a predefined event instead of a custom event.
Custom events are the events that you can create for your own requirements.
More info about the kit and events.
Configuration in AppGallery Connect
Firstly, you will need a Huawei developer account. If you don’t have one, click here and register. It will be activated in 1–2 days.
After signing in to AppGallery Connect, you can add a new project or select an existing project. In the project you choose, add an app. While adding app, make sure you enter the package name right. It should be the same as your Flutter project’s package name.
Also, make sure you set data storage location, enable Analytics kit and add SHA-256 fingerprint to AppGallery Connect.
How to generate SHA-256 Fingerprint?
In Android Studio, right click on android folder under your project and select Flutter > Open Android module in Android Studio.
On the right panel, select Gradle and follow the steps that are shown in the picture below. Open signingReport and there is your SHA-256 fingerprint.
Copy the code and paste it on the project settings in the AppGallery Connect.
Integrate HMS to your project
Download agconnect-services.json file and place it under project_name > android > app.
Add Signing Configuration
Create a file named key.properties under android folder and add your signing configs here.
storeFile file(‘<keystore_file>.jks’)
storePassword ‘<keystore_password>’
keyAlias ‘<key_alias>’
keyPassword ‘<key_password>’
Define your key.properties file by adding the code below, before android block in your app-level build.gradle file.
Code:
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file(‘key.properties’)
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
TO-DOs in project-level build.gradle
Code:
buildscript {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'} //add this line
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.huawei.agconnect:agcp:1.1.1.300' //add this line
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'} //add this line
}
}
TO-DOs in app-level build.gradle
Code:
defaultConfig {
...
minSdkVersion 19 //Increase this to 19
}
//Add these lines
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
//Edit buildTypes
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
//Add dependencies
dependencies {
implementation 'com.huawei.agconnect:agconnect-core:1.0.0.300'
implementation 'com.huawei.hms:hianalytics:5.0.1.300'
}
apply plugin: 'com.huawei.agconnect' //Add this line to the bottom of the page
Add Analytics Kit to your project
There are 2 ways to do this step.
1) Go to developer website and download plugin. In Android Studio create a new folder in your root directory and name it “hms”. Unzip the plugin and paste it in “hms” folder.
Then, go to pubspec.yaml and add the plugin under dependencies.
2) This way is much easier and also more familiar to Flutter developers. In pub.dev copy the plugin and add it under dependencies as usual.
For both ways, after running pub get command, the plugin is ready to use!
For more information about HMS Core integration, click.
We are all done. Let’s begin coding.
I will make a tiny and very easy game that I belive most of you know the concept: Guess the number!
As you play the game and try to guess the number, Huawei Analytics Kit will collect statistics how many times you guessed.
Make a simple game with Flutter
First, let’s write the method to create a random number. You should import ‘dart:math’ for this.
Code:
_setRandomNumber() {
Random random = Random();
int number = random.nextInt(100); // from 0 to 99 included
return number;
}
And call it in initState
Code:
@override
void initState() {
randomNumber = _setRandomNumber();
super.initState();
}
We will need a TextField and a button to check user’s guess.
Code:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: "Enter Your Guess [0-99]",
border: new OutlineInputBorder(borderSide: BorderSide()),
),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
onChanged: (value) {
guess = int.parse(value);
},
enabled: _isFound ? false : true, //If user guesses the number right, textfield will be disabled
),
RaisedButton(
child: Text("OK!"),
onPressed: () {
if (!_isFound) {
_controller.text = "";
_count++;
_compareValues();
}
},
),
],
)
We need a method if the user guessed the number right or not.
Code:
_compareValues() {
if (guess == randomNumber) {
setState(() {
_isFound = true;
_message =
"Correct! The number was $randomNumber.\nYou guessed it in $_count times.";
});
} else if (guess > randomNumber) {
setState(() {
_message = "Lower!";
});
} else {
setState(() {
_message = "Higher!";
});
}
}
}
Let’s add a message Text in Column widget to give hints to user, also a replay button.
Code:
Column(
...
Text(
_message,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 24),
),
_isFound //If user guesses the number right, iconButton will appear, otherwise it won't
? IconButton(
icon: Icon(
Icons.refresh,
size: 40,
),
onPressed: () {
setState(() {
//reset all variables and set a new random number.
randomNumber = _setRandomNumber();
_isFound = false;
_count = 0;
_message = "";
});
},
)
: Text("")
],
),
We have done a simple but fun game. Let’s play it!
Define HMS Analytics Kit and send events
As we’re done with the widgets, we will define the kit and enable logs.
Code:
class _MyHomePageState extends State<MyHomePage> {
final HMSAnalytics hmsAnalytics = new HMSAnalytics();
Future<void> _enableLog() async {
await hmsAnalytics.enableLog();
}
...
@override
void initState() {
_enableLog();
randomNumber = _setRandomNumber();
super.initState();
}
}
Once we call _enableLog(), we are ready to see auto collected events on AppGallery Connect.
What about our custom events? How can we send custom events and see them?
We have _count variable and every time user clicks OK! button, it increases. Now we will map it and send it as a custom event. We need a name for custom event, and a map value.
Code:
Future<void> _sendEvent(int count) async {
String name = "USERS_RESULTS";
Map<String, String> value = {
'number_of_guesses': count.toString()
};
await hmsAnalytics.onEvent(name, value);
}
And we call it when we are sure that user guessed the number right. In _compareValues method.
Code:
_compareValues() {
if (guess == randomNumber) {
...
_sendEvent(_count); //We know that user guessed the number right.
} else if (guess > randomNumber) {
...
} else {
...
}
}
}
Let’s go back to AppGallery Connect. In the left panel, under Management section click Events.
After _sendEvent builds for the first time, you can see your custom event with the name you have entered in your code. Click Edit.
Add your attribute and click Save.
On the left panel, click Real Time Monitoring under Overview.
Now you can see the attribute and its value in your custom event. Also you can see how many times you get this value and its proportion of all values.
Let’s play our game a few times more.
Despite I am the only user, you see 2 users in AG Connect. That’s because I uninstalled the app and installed again. Now I have a different AAID as I mentioned in the first part.
Under the graphics, there is event analysis. Here you can see all events, all attributes you’ve added and statistics for both events and attributes. 11 of them are custom events that I have sent by playing the game. And rest are collected automatically.
You can find full code in my github page. Here is the link for you.
ozkulbeng/FlutterHMSAnalyticsKitTutorial
Conclusion
In this article you have learned how to integrate HMS Analytics to your Flutter projects, send custom events and monitor them in AppGallery Connect. You can use custom events in your apps to see user behaviors, so that you can improve your app depend on them.
Thank you for reading this article, I hope you enjoyed it.
References
Analytics Kit Document
HMS-Core/hms-ananlytics-demo-android

sujith.e said:
Huawei Analytics will track fragment reports
Click to expand...
Click to collapse
Quite right. It really helps a lot

Related

Sending Push Notifications on Flutter with Huawei Push Kit Plugin

More information like this, you can visit HUAWEI Developer Forum​
Push notifications offer a great way to increase your application’s user engagement and boost your retention rates by sending meaningful messages or by informing your users about your application. These messages can be sent at any time and even if your app is not running at that time.
Huawei Push Kit
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Huawei Push Kit is a messaging service developed by Huawei for developers to send messages to apps on users’ device in real time. Push Kit supports two types of messages: notification messages and data messages, which we will cover both in this tutorial. You can send notifications and data messages to your users from your server using the Push Kit APIs or directly from the AppGallery Push Kit Console.
Recently we released the Huawei Push Kit Plugin for Flutter to make the integration of Push Kit with your Flutter apps easily.
You can find the plugin on from the link below.
Github: https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-push
We will use this plugin throughout the tutorial, so let’s get started.
Configure your project on AppGallery Connect
First of all you should have a Huawei Developer Account to use the Huawei Mobile Services and thus the Huawei Push Kit. I will not get into details about how you create the developer account since it is very straightforward and out of the scope of this tutorial but you can find all the details here.
Let’s start by creating a new project on Huawei Developer Console. If you already created a project before you can skip this step. Just make sure you have set the Data Storage Location and entered the SHA-256 fingerprint.
Create an app and enable Push Kit
1. Go to Huawei Developer Console and select Huawei Push under Development section. Press the “New App” button on the top right corner to create a new app. You can refer to this article if you came across any problem.
2. You’ll be forwarded to Push Kit page after the creation of your app, you can also navigate here from the side menu. Enable the Push Kit service by clicking “Enable Now”.
3. After enabling Push Kit, console will prompt you to enter the package name and it will redirect you to Project Settings. You can manually enter the package name or you can upload your package to set it automatically. I choose the option to enter manually which is in my case “com.example.flutter_push_kit_tutorial”. You can find this from the first lines of your AndroidManifest.xml file under <your_flutter_project>/android/app/src/AndroidManifest.xml
4. On the Project Settings page set the Data Storage Location as Germany. This is needed to store and send out our push messages.
Generate and Configure Signing Certificate Fingerprint
A signing certificate fingerprint is needed to verify the authenticity of our app when it attempts to access the HMS Push Kit through the HMS Core SDK. So before we able to use the push service, we must generate a signing certificate and configure it in AppGallery Connect. We will also use this certificate later in the Flutter project configuration.
Before generating the signing certificate we must have the JDK installed. This is installed by default with Android Studio. Go to the Java/JDK installation’s bin directory in your pc and open cmd or powershell to run the following command:
keytool-genkey-keystore <keystore-file> -storepass <keystore-pass> -alias <key-alias> -keypass <key-pass> -keysize 2048 -keyalg RSA -validity <validity-period>
The fields that should be filled in the command are as follows:
· <keystore-file> is the path to the app’s signature file. File extension must be .jks or .keystore. For example; C:\key.jks
· <keystore-pass> is the password of your keystore.
· <key-alias> is the alias name of key that will be stored in your keystore.
· <key-pass> is the password of your key.
· <validity-period> Amount of days the key will be valid with this keystore.
Example command:
Code:
keytool -genkey -keystore C:\Users\Username\key.jks -storepass 123456 -alias pushkitkey -keypass 123456 -keysize 2048 -keyalg RSA -validity 36500
Note that you can run this command anywhere if you configured your system environment variables to include JDK folders.
Now that we generated our certificate we need to obtain the SHA-256 fingerprint and add it to the project settings on the AppGallery Connect. To obtain the fingerprints run the command below at the same directory you generated the keystore (Java/JDK bin folder where keytool located)
Code:
keytool -list -v -keystore C:\Users\Username\key.jks
Obtaining SHA-256 Fingerprint from powershell
Copy and paste the SHA-256 fingerprint you obtained to SHA-256 field on the project settings page. Make sure this value has set before you move on. After everything is done, your project settings should look like below.
Completed AppGallery Connect Configuration
Integrate HMS to your Flutter project
Now that we are done with the configuration on the AppGallery Connect let’s move to Flutter part to finish the setup.
Add the Huawei Push Kit Plugin dependency to the project’s pubspec.yaml file and run flutter pub get to load the plugin.
Code:
dependencies:
flutter:
sdk: flutter
huawei_push: 4.0.4+300
For integration with the Huawei Push Kit as well as other Huawei Mobile Services we must download agconnect-services.json file from project settings>app information (where we entered the fingerprint before) and add it to the folder :<your_flutter_project>/android/app
Your project should look like this after adding the services
Add the lines below to the project level build.gradle file
(your_flutter_project/android/build.gradle)
Code:
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // Add this line
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.huawei.agconnect:agcp:1.3.1.300' // Add this line
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' } // Add this line
}
}
/* other configurations/*
Create a key.properties file inside the android folder for gradle to read the keystore values that we generated before.
Code:
storePassword=<your_keystore_pass>
keyPassword=<your_key_pass>
keyAlias=<alias_you_entered_before>
storeFile=<path_to_keystore.jks>
On the first line of app level build.gradle located on:
your_flutter _project/android/app/build.gradle
add this line to read the values of key.properties file.
Code:
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
Increase your minSdkVersion to 17 and make the following changes on the same app level build.gradle file
Code:
android {
/*
Other configurations
…
*/
defaultConfig {
// The package name below and on AppGallery Connect should be the same
applicationId "com.example.flutter_push_kit_tutorial"
minSdkVersion 17 // Increase this to 17
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
// Add this part
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
// Edit here
buildTypes {
debug {
signingConfig signingConfigs.release
}
release {
signingConfig signingConfigs.release
}
}
}
Add this line to the end of the same file
Code:
apply plugin: 'com.huawei.agconnect' // Add this line (this needs to be at the bottom of your build.gradle)
Important Note
If you are planning to get a release apk you also need to configure proguard rules to prevent HMS Core SDK from being obfuscated. As stated in this documentation Google’s R8 compiler automatically does shrinking and obfuscating on release builds to reduce the size of your app.
Add following lines to proguard-rules.pro file, create the file inside the android folder if you don’t have it already. You may need further configuration on build.gradle, please refer to the documentation above or this stackoverflow issue.
Code:
## 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.**
## HMS Core SDK
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
Testing Push Notification
Now that we are ready to use the Push Kit in our Flutter project, let’s get a token for testing the push notification and then we can move with a little bit more complex example.
To receive the token we must initialize an EventChannel and listen the changes from the stream. I’ve initialized the channel and requested a token in the initState of the HomeScreen widget.
Code:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:huawei_push/push.dart';
import 'package:huawei_push/constants/channel.dart' as Channel;
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
String _token = '';
static const EventChannel TokenEventChannel =
EventChannel(Channel.TOKEN_CHANNEL);
@override
void initState() {
super.initState();
initPlatformState();
getToken();
}
Future<void> initPlatformState() async {
if (!mounted) return;
TokenEventChannel.receiveBroadcastStream()
.listen(_onTokenEvent, onError: _onTokenError);
}
void _onTokenEvent(Object event) {
// This function gets called when we receive the token successfully
setState(() {
_token = event;
});
print('Push Token: ' + _token);
Push.showToast(event);
}
void _onTokenError(Object error) {
setState(() {
_token = error;
});
Push.showToast(error);
}
void getToken() async {
await Push.getToken();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Rest of the widget...
);
}
}
We got the push token after running our app and now we can test the push notification by sending one from the Push Kit Console. Navigate to Push Kit > Add Notification and complete the required fields, you should enter the token we got earlier to the specified device in the push scope part. You can test the notification immediately by pressing test effect button or you can submit your notification.
Sending Push Notification from Huawei Push Kit Console
We have received our first notification
Subscribing to a topic and receiving data messages
Topics are like separate messaging channels that we can send notifications and data messages to. Devices, subscribe to these topics for receiving messages about that subject. For example, users of a weather forecast app can subscribe to a topic that sends notifications about the best weather for exterminating pests. You can check here for more use cases.
Data Messages are customized messages that their content is defined by you and parsed by your application. After receiving these messages, the system transfers it to the app instead of directly displaying the message. App then can parse the message and can trigger some action.
In my example I will define a ‘coupon’ topic that users can subscribe to receive coupons. And then I will send a data message which includes the coupon from the Push Kit Console. (Note that this can also be done by using the Push Kit API)
Let’s define the Coupon class to convert our data message to a coupon object
Code:
class Coupon {
String title;
String body;
String couponCode;
Coupon({this.title, this.body, this.couponCode});
Coupon.fromJson(Map<String, dynamic> json) {
title = json['title'];
body = json['body'];
couponCode = json['couponCode'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['title'] = this.title;
data['body'] = this.body;
data['couponCode'] = this.couponCode;
return data;
}
}
In home_screen.dart I’ve added a data message event channel just like we did in the token part to receive the messages. And then I’ve added a subscription function and a method to show a dialog if we receive a coupon.
Code:
/*
Imports...
*/
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool _subscribed = false;
static const EventChannel DataMessageEventChannel =
EventChannel(Channel.DATA_MESSAGE_CHANNEL);
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
if (!mounted) return;
DataMessageEventChannel.receiveBroadcastStream()
.listen(_onDataMessageEvent, onError: _onDataMessageError);
}
void _onDataMessageEvent(Object event) {
Map<String, dynamic> dataObj = json.decode(event);
if (dataObj['type'] == 'coupon') {
Coupon coupon = Coupon.fromJson(dataObj);
showCouponDialog(coupon);
} else {
print('Unsupported Data Message Type');
}
Push.showToast(event);
}
void _onDataMessageError(Object error) {
Push.showToast(error);
}
void subscribeToCoupons() async {
setState(() {
_subscribed = true;
});
String topic = 'coupon';
dynamic result = await Push.subscribe(topic);
Push.showToast(result);
}
showCouponDialog(Coupon coupon) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Container(
child: Text(
coupon.title.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.green,
fontSize: 25,
),
)),
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
content: Container(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(coupon.body),
SizedBox(
height: 10,
),
Text(
coupon.couponCode,
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
MaterialButton(
color: Colors.green,
child: Text(
'Claim Now',
style: TextStyle(color: Colors.white),
),
onPressed: () => Navigator.pop(context),
)
],
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HMS Push Kit Example'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('Subscribe to coupon topic to get free coupons'),
SizedBox(
height: 20,
),
OutlineButton(
onPressed: _subscribed ? null : () => subscribeToCoupons(),
child: Text('Subscribe Now'),
borderSide: BorderSide(color: Colors.green),
textColor: Colors.green,
),
],
),
),
);
}
}
Our app is shown below, let’s subscribe to coupon topic by pressing the button.
Now on Huawei Push Kit Console, create a data message like the image below and send it to the coupon topic subscribers.
Configuring the data message from the Push Kit Console
After sending the data message to our coupon subscribers we should see the coupon dialog with the message we have sent.
It must be your lucky day.
I am leaving the project’s github link in case you want to check it from there or try this example by yourself:
https://github.com/atavci/FlutterPushKitTutorial
Conclusion
Now you know how to use the Huawei Push Kit for your Flutter Projects. You can use this information to connect your existing users or add extra functionality that will attract even more users. Like every awesome feature, notifications should be handled with extra care; since nobody likes to get bombarded with them.
I leave some references for further reading, you can also ask questions on the comments section, I would happily answer them.
Have a great day and successful builds!
From:
https://medium.com/huawei-developers/sending-push-notifications-on-flutter-with-huawei-push-kit-plugin-534787862b4d

Hand Keypoint Detection with HMS ML Kit Explained (with a Demo Project)

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Hand keypoint detection is the process of finding fingertips, knuckles and wrists in an image. Hand keypoint detection and hand gesture recognition is still a challenging problem in computer vision domain. It is really a tough work to build your own model for hand keypoint detection as it is hard to collect a large enough hand dataset and it requires expertise in this domain.
Hand keypoint detection can be used in variety of scenarios. For example, it can be used during artistic creation, users can convert the detected hand keypoints into a 2D model, and synchronize the model to a character’s model to produce a vivid 2D animation. You can create a puppet animation game using the above idea. Another example may be creating a rock paper scissors game. Or if you take it further, you can create a sign language to text conversion application. As you see varieties to possible usage scenarios are abundant and there is no limit to ideas.
Hand keypoint detection service is a brand-new feature that is added to Huawei Machine Learning Kit family. It has recently been released and it is making developers and computer vision geeks really excited! It detects 21 points of a hand and can detect up to ten hands in an image. It can detect hands in a static image or in a camera stream. Currently, it does not support scenarios where your hand is blocked by more than 50% or you wear gloves. You don’t need an internet connection as this is a device side capability and what is more: It is completely free!
It wouldn’t be a nice practice only to read related documents and forget about it after a few days. So I created a simple demo application that counts fingers and tells us the number we show by hand. I strongly advise you to develop your hand keypoint detection application beside me. I developed the application in Android Studio in Kotlin. Now, I am going to explain you how to build this application step by step. Don’t hesitate to ask questions in the comments if you face any issues.
1.Firstly, let’s create our project on Android Studio. I named my project as HandKeyPointDetectionDemo. I am sure you can find better names for your application. We can create our project by selecting Empty Activity option and then follow the steps described in this post to create and sign our project in App Gallery Connect.
2. In HUAWEI Developer AppGallery Connect, go to Develop > Manage APIs. Make sure ML Kit is activated.
3. Now we have integrated Huawei Mobile Services (HMS) into our project. Now let’s follow the documentation on developer.huawei.com and find the packages to add to our project. In the website click Developer / HMS Core/ AI / ML Kit. Here you will find introductory information to services, references, SDKs to download and others. Under ML Kit tab follow Android / Getting Started / Integrating HMS Core SDK / Adding Build Dependencies / Integrating the Hand Keypoint Detection SDK. We can follow the guide here to add hand detection capability to our project. We have also one meta-data tag to be added into our AndroidManifest.xml file. After the integration your app-level build.gradle file will look like this.
Code:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.huawei.agconnect'
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.demo.handkeypointdetection"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
//AppGalleryConnect Core
implementation 'com.huawei.agconnect:agconnect-core:1.3.1.300'
// Import the base SDK.
implementation 'com.huawei.hms:ml-computer-vision-handkeypoint:2.0.2.300'
// Import the hand keypoint detection model package.
implementation 'com.huawei.hms:ml-computer-vision-handkeypoint-model:2.0.2.300'
}
Our project-level build.gradle file:
Code:
buildscript {
ext.kotlin_version = "1.4.0"
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
And don’t forget to add related meta-data tags into your AndroidManifest.xml.
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.handkeypointdetection">
<uses-permission android:name="android.permission.CAMERA" />
<application
...
<meta-data
android:name="com.huawei.hms.ml.DEPENDENCY"
android:value= "handkeypoint"/>
</application>
</manifest>
4. I created a class named HandKeyPointDetector. This class will be called from our activity or fragment. Its init method has two parameters context and a viewgroup. We will add our views on rootLayout.
Code:
fun init(context: Context, rootLayout: ViewGroup) {
mContext = context
mRootLayout = rootLayout
addSurfaceViews()
}
5. We are going to detect hand key points in a camera stream, so we create a surfaceView for camera preview and another surfaceView to draw somethings. The surfaceView that is going to be used as overlay should be transparent. Then, we add our views to our rootLayout passed as a parameter from our activity. Lastly we add SurfaceHolder.Callback to our surfaceHolder to know when it is ready.
Code:
private fun addSurfaceViews() {
val surfaceViewCamera = SurfaceView(mContext).also {
it.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
mSurfaceHolderCamera = it.holder
}
val surfaceViewOverlay = SurfaceView(mContext).also {
it.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
mSurfaceHolderOverlay = it.holder
mSurfaceHolderOverlay.setFormat(PixelFormat.TRANSPARENT)
mHandKeyPointTransactor.setOverlay(mSurfaceHolderOverlay)
}
mRootLayout.addView(surfaceViewCamera)
mRootLayout.addView(surfaceViewOverlay)
mSurfaceHolderCamera.addCallback(surfaceHolderCallback)
}
6. Inside our surfaceHolderCallback we override three methods: surfaceCreated, surfacehanged and surfaceDestroyed.
Code:
private val surfaceHolderCallback = object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
createAnalyzer()
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
prepareLensEngine(width, height)
mLensEngine.run(holder)
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
mLensEngine.release()
}
}
7. createAnalyzer method creates MLKeyPointAnalyzer with settings. If you want you can use default settings also. Scene type can be keypoint and rectangle around hands or we can use TYPE_ALL for both. Max hand results can be up to MLHandKeypointAnalyzerSetting.MAX_HANDS_NUM which is 10 currently. As we will count fingers of 2 hands, I set it to 2.
Code:
private fun createAnalyzer() {
val settings = MLHandKeypointAnalyzerSetting.Factory()
.setSceneType(MLHandKeypointAnalyzerSetting.TYPE_ALL)
.setMaxHandResults(2)
.create()
mAnalyzer = MLHandKeypointAnalyzerFactory.getInstance().getHandKeypointAnalyzer(settings)
mAnalyzer.setTransactor(mHandKeyPointTransactor)
}
8. LensEngine is responsible for handling camera frames for us. All we need to do is to prepare it with right dimensions according to orientation, choose the camera we want to work with, apply fps an so on.
Code:
private fun prepareLensEngine(width: Int, height: Int) {
val dimen1: Int
val dimen2: Int
if (mContext.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
dimen1 = width
dimen2 = height
} else {
dimen1 = height
dimen2 = width
}
mLensEngine = LensEngine.Creator(mContext, mAnalyzer)
.setLensType(LensEngine.BACK_LENS)
.applyDisplayDimension(dimen1, dimen2)
.applyFps(5F)
.enableAutomaticFocus(true)
.create()
}
9. When you no longer need the analyzer stop it and release resources.
Code:
fun stopAnalyzer() {
mAnalyzer.stop()
}
10. As you can see in step-7 we used mHandKeyPointTransactor. It is a custom class that we created named HandKeyPointTransactor, which inherits MLAnalyzer.MLTransactor<MLHandKeypoints>. It has two overriden methods inside. transactResult and destroy. Detected results will fall inside transactResult method and then we will try to find the number.
Code:
override fun transactResult(result: MLAnalyzer.Result<MLHandKeypoints>?) {
if (result == null)
return
val canvas = mOverlay?.lockCanvas() ?: return
//Clear canvas.
canvas.drawColor(0, PorterDuff.Mode.CLEAR)
//Find the number shown by our hands.
val numberString = analyzeHandsAndGetNumber(result)
//Find the middle of the canvas
val centerX = canvas.width / 2F
val centerY = canvas.height / 2F
//Draw a text that writes the number we found.
canvas.drawText(numberString, centerX, centerY, Paint().also {
it.style = Paint.Style.FILL
it.textSize = 100F
it.color = Color.GREEN
})
mOverlay?.unlockCanvasAndPost(canvas)
}
11. We will check hand by hand and then finger by finger to find the fingers that are up to find the number.
Code:
private fun analyzeHandsAndGetNumber(result: MLAnalyzer.Result<MLHandKeypoints>): String {
val hands = ArrayList<Hand>()
var number = 0
for (key in result.analyseList.keyIterator()) {
hands.add(Hand())
for (value in result.analyseList.valueIterator()) {
number += hands.last().createHand(value.handKeypoints).getNumber()
}
}
return number.toString()
}
For more information, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202369245767250343&fid=0101187876626530001

Intermediate: Site kit Search Capabilities in Food DeliveryApp in Flutter – Part 2

Introduction
In this article, we will be integrating other Search features of Site kit, you can find previous article here, and Huawei Site Kit provides core capabilities to developer to quickly build apps with which users can explore world around them seamlessly. Huawei Site kit provides following Search capabilities to developer as shown below.
Keyword search: returns the place list based on the keywords entered by user.
Nearby place search: Searches for nearby location based on current location of the user’s device.
Place detail search: Search for details about the place.
Place search suggestion: Returns list of suggested places.
Autocomplete: Returns an autocomplete place and a list of suggested places based on the entered keyword.
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1. Create flutter project
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Step 2. Add the App level gradle dependencies, choose inside project Android > app > build.gradle.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Add root level gradle dependencies
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 3: Add the below permissions in Android Manifest file.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARES_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Step 4: Add plugin path in pubspec.yaml file under dependencies.
Step 5: Create a project in AppGallery Connect, find here.
pubspec.yaml
Code:
name: sample_one
description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_map:
path: ../huawei_map/
huawei_location:
path: ../huawei_location/
huawei_safetydetect:
path: ../huawei_safetydetect
huawei_site:
path: ../huawei_site
http: ^0.12.2
rflutter_alert: ^2.0.2
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
# add this line to your dependencies
toast: ^0.1.5
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
Declare and instantiate service object
Code:
Future<void> initmySearchService() async {
searchService = await SearchService.create(Uri.encodeComponent(API_KEY));
}<strong> </strong>
How to I call QueryAutoCompleteRequest api ?
Code:
void autocomplete(String value) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
// Create QueryAutocompleteRequest and its body.
QueryAutocompleteRequest request = QueryAutocompleteRequest(query: value);
// Create QueryAutocompleteResponse object.
// Call queryAutocomplete() method.
// Assign the results.
QueryAutocompleteResponse response =
await searchService.queryAutocomplete(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
locations.clear();
entries.clear();
for (String key in data.keys) {
if (key == 'sites') {
data2 = data[key];
for (var element in data2) {
setState(() {
entries.add(element['name'] + "\n" + element['formatAddress']);
locations.add(new LatLng(
element['location']['lat'], element['location']['lng']));
});
}
}
}
}
}
How to I call QuerySuggestionRequest api ?
Code:
void querySuggestionSearch(String value) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
QuerySuggestionRequest request = QuerySuggestionRequest();
request.query = value;
request.location = Coordinate(lat: 12.893478, lng: 77.334595);
request.language = "en";
request.countryCode = "IN";
request.radius = 5000;
// Create QuerySuggestionResponse object.
// Call querySuggestion() method.
// Assign the results.
QuerySuggestionResponse response =
await searchService.querySuggestion(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
entries.clear();
for (String key in data.keys) {
if (key == 'sites') {
data2 = data[key];
for (var element in data2) {
setState(() {
entries.add(element['name'] + "\n" + element['formatAddress']);
locations.add(new LatLng(
element['location']['lat'], element['location']['lng']));
});
}
}
}
}
}
How to I call DetailSearchRequest api ?
Code:
void placeDetailSearch(String siteId) async {
// Declare an SearchService object and instantiate it. which i done in above initSearchService()
DetailSearchRequest request = DetailSearchRequest();
request.siteId = siteId;
request.language = "en";
// Create DetailSearchResponse object.
// Call detailSearch() method.
// Assign the results.
DetailSearchResponse response = await searchService.detailSearch(request);
if (response != null) {
Map<String, dynamic> data = json.decode(response.toJson());
List<dynamic> data2;
setState(() {
result = data['site'].toString();
});
} else {
print("Response is NULL");
}
}
Result
Note: Place detail search takes sit id as input and gives site information as result.
Tricks and Tips
Make sure that you have downloaded latest plugin.
Make sure that updated plugin path in yaml.
Make sure that plugin unzipped in parent directoryof project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added in build file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
Conclusion
In this article, we have learnt how to integrate Huawei Site kit Search capabilities for DeliveryApp in flutter. Where user can search for specific hotel or restaurants in the search box and clicks on the result to find the list of orders. Similar way you can use Huawei Site kit as per user requirement in your application.
Thank you so much for reading, I hope this article helps you to understand the Huawei Site kit Search capabilities in flutter.
Reference
Site kit
Site kit plugin
Original Source

Intermediate: Integration of Huawei Ads with Game Services in Flutter (Cross platform)

Introduction
In this article, we will be integrating Huawei Ads and Game Services kit in flutter application. You can access to range of development capabilities. You can promote your game quickly and more efficiently to Huawei’s vast users as Huawei Game Services allows users to login game with Huawei IDs. You can also use the service to quickly implement achievements, game events, and game addiction prevention functions and perform in-depth game operations based on user and content localization. Huawei Ads kit helps developer to monetize application.
Huawei supports following Ads types
Banner
Interstitial
Native
Reward
Splash
Instream(Roll)
Huawei Game Services Capabilities
Game Login
Achievements
Floating window*
Game Addiction prevention*
Events
Leaderboards
Save Games*
Player statistics*
Access to Basic Game Information*
Note: Restricted to regions (*)
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone with API 4.x.x or above (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1. Create flutter project.
Step 2. Add the App level gradle dependencies, choose inside project Android > app > build.gradle.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Add root level gradle dependencies.
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.2.301'
Step 3: Add the below permissions in Android Manifest file.
Code:
<uses-permission android:name="android.permission.INTERNET" />
Step 4: Add plugin path in pubspec.yaml file under dependencies.
Step 5: Create a project in AppGallery Connect, find here.
pubspec.yaml
Code:
name: gameservice234demo
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_account:
path: ../huawei_account
huawei_gameservice:
path: ../huawei_gameservice
huawei_ads:
path: ../huawei_ads_301
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
How do I launch or initialize the Ads SDK?
Code:
HwAds.init();
How do I load Splash Ads?
Code:
void showSplashAd() {
SplashAd _splashAd = createSplashAd();
_splashAd
..loadAd(
adSlotId: "testq6zq98hecj",
orientation: SplashAdOrientation.portrait,
adParam: AdParam(),
topMargin: 20);
Future.delayed(Duration(seconds: 7), () {
_splashAd.destroy();
});
}
static SplashAd createSplashAd() {
SplashAd _splashAd = new SplashAd(
adType: SplashAdType.above,
ownerText: ' Huawei SplashAd',
footerText: 'Test SplashAd',
); // Splash Ad
return _splashAd;
}
How do I load Native Ad?
Code:
static NativeAd createNativeAd() {
NativeStyles stylesSmall = NativeStyles();
stylesSmall.setCallToAction(fontSize: 8);
stylesSmall.setFlag(fontSize: 10);
stylesSmall.setSource(fontSize: 11);
NativeAdConfiguration configuration = NativeAdConfiguration();
configuration.choicesPosition = NativeAdChoicesPosition.topLeft;
return NativeAd(
// Your ad slot id
adSlotId: "testu7m3hc4gvm",
controller: NativeAdController(
adConfiguration: configuration,
listener: (AdEvent event, {int? errorCode}) {
print("Native Ad event : $event");
}),
type: NativeAdType.small,
styles: stylesSmall,
);
}
How do I load Interstitial Ad?
Code:
void showInterstitialAd() {
InterstitialAd interstitialAd =
InterstitialAd(adSlotId: "teste9ih9j0rc3", adParam: AdParam());
interstitialAd.setAdListener = (AdEvent event, {int? errorCode}) {
print("InterstitialAd event : $event");
};
interstitialAd.loadAd();
interstitialAd.show();
}
How do I load Rewarded Ad?
Code:
static Future<void> showRewardAd() async {
RewardAd rewardAd = RewardAd();
await rewardAd.loadAd(
adSlotId: "testx9dtjwj8hp",
adParam: AdParam(),
);
rewardAd.show();
rewardAd.setRewardAdListener =
(RewardAdEvent event, {Reward? reward, int? errorCode}) {
print("RewardAd event : $event");
if (event == RewardAdEvent.rewarded) {
print('Received reward : ${reward!.toJson().toString()}');
}
};
}
How do I launch or initialize the game?
Code:
void init() async {
await JosAppsClient.init();
}
Use Huawei ID for login
Code:
Future<void> login() async {
helper = new HmsAuthParamHelper()
..setIdToken()
..setAccessToken()
..setAuthorizationCode()
..setEmail()
..setProfile();
huaweiId = await HmsAuthService.signIn(authParamHelper: helper);
if (huaweiId != null) {
setState(() {
isLoggedIn = true;
msg = huaweiId!.displayName;
loginLabel = "Logged in as";
print(msg);
});
getPlayer();
} else {
setState(() {
msg = " Inside else ";
});
}
}
How do I get Achievements list?
Code:
Future<void> getAchievements() async {
try {
List<Achievement> result =
await AchievementClient.getAchievementList(true);
print("Achievement:" + result.toString());
} on PlatformException catch (e) {
print("Error on getAchievementList API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
}
How do I displaying the Achievements List Page of HUAWEI AppAssistant using Intent?
Code:
void showAchievementsIntent() {
try {
AchievementClient.showAchievementListIntent();
} on PlatformException catch (e) {
print("Error on showAchievementListIntent API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
}
How do I call Floating window?
Code:
try {
await BuoyClient.showFloatWindow();
} on PlatformException catch (e) {
print("Error on showFloatWindow API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
How do I get All Events?
Code:
Future<void> getEvents() async {
try {
List<GameEvent> result = await EventsClient.getEventList(true);
print("Events: " + result.toString());
} on PlatformException catch (e) {
print("Error on getEventList API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
}
How do I submit an Event?
Code:
Future<void> sendEvent(String eventId) async {
try {
await EventsClient.grow(eventId, 1);
print("************** Event sent **************");
} on PlatformException catch (e) {
print("Error on grow API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
}
How do I get All Leaderboard data?
Code:
Future<void> getLeaderboardList() async {
// check the leaderboard status
int result = await RankingClient.getRankingSwitchStatus();
// set leaderboard status
int result2 = await RankingClient.setRankingSwitchStatus(1);
List<Ranking> rankings = await RankingClient.getAllRankingSummaries(true);
print(rankings);
//To show RankingIntent
RankingClient.showTotalRankingsIntent();
}
How do I submit the ranking score?
Code:
try {
int score = 102;
RankingClient.submitRankingScores(rankingId, score);
} on PlatformException catch (e) {
print("Error on submitRankingScores API, Error: ${e.code}, Error Description:${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
Or
try {
int score = 125;
ScoreSubmissionInfo result = await RankingClient.submitScoreWithResult(rankingId, score);
} on PlatformException catch (e) {
print("Error on submitScoreWithResult API, Error: ${e.code}, Error Description: ${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
How do I displaying the Leaderboard List Page of HUAWEI AppAssistant using Intent?
Code:
void showLeaderboardIntent() {
try {
RankingClient.showTotalRankingsIntent();
} on PlatformException catch (e) {
print("Error on showLeaderboardListIntent API, Error: ${e.code}, Error Description:
${GameServiceResultCodes.getStatusCodeMessage(e.code)}");
}
}
Result
Tricks and Tips
Make sure that you have downloaded latest plugin.
Make sure that updated plugin path Ads in yaml.
Make sure that plugin unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added in build file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in ag-connect.
Game Services previous article you can check out here
Conclusion
In this article, we have learnt how to integrate capabilities of Huawei Ads with Game Services kit in flutter application. You can promote your game quickly and more efficiently to Huawei’s vast users as Huawei Game Services allows users to login with Huawei IDs and this can be achieved by implementing its capabilities in your application. Developer can easily integrate and monetize the application which helps developer to grow financial long with application. Similar way you can use Huawei Ads with Game Services as per user requirement in your application.
Thank you so much for reading, I hope this article helps you to understand the Huawei Ads with Game Services capabilities in flutter.
Reference
GameServices Kit
Plutter Plugin Game services
Ads Kit
Original Source

Pygmy Collection Application Part 4 (Analytics Kit Custom Events)

Introduction​
In my last article, I have explained how to integrate an account kit finance application. Have a look into Pygmy collection application Part 1 (Account kit).
In this article, we will learn how to integrate Analytics kit kit in Pygmy collection finance application.
Adding Events with Huawei Analytics Kit
This guide walks you through the process of building application that uses Huawei Analytics Kit to trigger event and can find data on the console.
What You Will Build
You will build an application that triggers events, setting user properties, logging custom event etc.
What You Need
About 10 minutes
A favorite text editor or IDE(For me Android Studio)
JDK 1.8 or later
Gradle 4+
SDK platform 19
What is Mobile analytics?
Mobile analytics captures data from mobile app, website, and web app visitors to identify unique users, track their journeys, record their behaviour, and report on the app’s performance. Similar to traditional web analytics, mobile analytics are used to improve conversions, and are the key to crafting world-class mobile experiences.
How to complete this guide
When a person says that I know theoretical concept, only when he/she knows the answer for all WH questions. To complete this guide, lets understand all WH questions.
1. Who has to use analytics?
2. Which one to use?
3. What is Huawei Analytics kit?
4. When to use HMS Analytics kit?
5. Why to use analytics kit?
6. Where to use analytics Kit?
Once you get answer for all the above questions, then you will get theoretical knowledge. But to understand with result you should know answer for below question.
1. How to integrate Huawei analytics kit?
Who has to use the analytics kit?
The answer is very simple, the analytics kit will be used in the mobile/web application. So off course software developer has to use analytics kit.
Which one to use?
Since there are many analytics vendors in the market. But for mobile application I recommend Huawei analytics kit. Now definitely you will have question why? To answer this I’ll give some reasons.
Very easy to integrate.
Documentation is too good.
Community is too good. Response from community is so fast.
Moreover, it is very similar to other vendors, so no need to learn new things.
You can see events in real time.
What is Huawei Analytics kit?
Flutter Analytics plugin enables the communication between HMS Core analytics SDK and Flutter platform. This plugin exposed all the functionality which is provided by HMS core analytics SDK.
Huawei Analytics kit offers you a range of analytics models that helps you to analyse the users’ behaviour with predefined and custom events, you can gain a deeper insight into your users, products and content. It helps you to gain insight into that how users behave on different platforms based on the user behaviour events and user attributes reported through apps.
Huawei Analytics kit, our one-stop analytics platform provides developers with intelligent, convenient and powerful analytics capabilities, using this we can optimize apps performance and identify marketing channels.
Collect and report custom events.
Set a maximum of 25 user attributes.
Automate event collection and session calculation.
Preset event IDs and parameters.
When to use HMS Analytics kit?
Mobile app analytics are a developer’s best friend. It helps you gain understanding about that how users’ behaviour and app can be optimized to reach your goals. Without mobile app analytics, you would be trying out different things blindly without any data to back up your experiments.
That’s why it’s extremely important for developers to understand their mobile app analytics to track their progress while working towards achieving their goals.
Why to use analytics kit?
Mobile app analytics are essential to development process for many reasons. They give you insights into that how users are using your app, which parts of the app they interact with, and what actions they take within the app. You can use these insights to come up with an action plan to improve your product in future, like adding new features that the users seem to need, or improve existing ones in a way that would make the users lives easier, or removing features that the users don’t seem to use.
You’ll also gain insights into whether you’re achieving your goals for your mobile app, whether its revenue, awareness, or other KPIs, and then take the data you have to adjust your strategy and optimize your app to reach your further goals.
When it comes to why? Always everyone thinks about benefits.
Benefits of Analytics
App analytics helps you to drive ROI over every aspect of performance.
App analytics helps you to gather accurate data to better serve for customers.
App analytics allows you to drive personalized and customer-focused marketing.
App analytics allowss you to track individual and group achievements of marketing goals from campaigns.
App analytics offers data-driven insights into issues concerning churn and retention.
Where to use analytics Kit?
This is very important question, because you already know why to use the analytics kit. So wherever you want understand about user behaviour, which part of the application users are using regularly, which functionality of the application users are using more. In the scenario you can use analytics kit in either mobile/web application you can use the analytics kit.
Now start with practical
Till now you understood theoretical concept of the analytics kit. Now let’s start with the practical example, to understand about practical we should get answer for the below question.
How to integrate Huawei analytics kit in Android finance application?
To achieve this you need to follow couple of steps as follows.
1. Configure application on the AGC.
2. Client application development process.
Configure application on the AGC
Follow the steps.
Step 1: We need to register as a developer account in AppGallery Connect. If you are already developer ignore this step.
Step 2: Create an app by referring to Creating a Project and Creating an App in the Project
Step 3: Set the data storage location based on current location.
Step 4: Enabling Analytics Kit. Project setting > Manage API > Enable analytics kit toggle button.
Step 5: Generating a Signing Certificate Fingerprint.
Step 6: Configuring the Signing Certificate Fingerprint.
Step 7: Download your agconnect-services.json file, paste it into the app root directory.
Client application development process
Follow the steps.
Step 1: Create Android application in the Android studio (Any IDE which is your favorite)
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
How to integrate Ads Kit
1. Configure the application on the AGC.
2. Client application development process.
3. Testing a Splash Ad.
Client application development process
Follow the steps.
Step 1: Create an Android application in the Android studio (Any IDE which is your favorite).
Step 2: Add the App level Gradle dependencies. Choose inside project Android > app > build.gradle.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
dependencies {
implementation 'com.huawei.hms:hianalytics:5.1.0.300'
}
Root level gradle dependencies.
Code:
maven { url 'https://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 3: To allow HTTP and HTTPS network requests on devices with targetSdkVersion 28 or later, configure the following information in the AndroidManifest.xml file:
XML:
<application
...
android:usesCleartextTraffic="true"
>
...
</application>
Step 4: Initialize Ads kit activity or application class.
Step 5: Build Application.
HuaweiUserProperty.java
Java:
public class HuaweiUserProperty {
public enum KeyName {
USER_CUSTOMER_ID("user_session_id"),
USER_PHONE_NUMBER("user_phone_number");
String textValue;
KeyName(String textValue) {
this.textValue = textValue;
}
public String textValue() {
return textValue;
}
}
}
HuaweiEvenParams.java
Java:
public enum HuaweiEventParams {
temp;
public enum EventName {
TAP("tap"),
OPEN("open");
String textValue;
EventName(String textValue) {
this.textValue = textValue;
}
public String textValue() {
return textValue;
}
}
public enum Key {
PREVIOUS_SCREEN_NAME("previous_screen_name"),
SCREEN_NAME("screen_name"),
UI_ELEMENT("ui_element_name"),
DESCRIPTION("description_key"),
PARENT_SCREEN_NAME("parent_screen_name"),
CUSTOMER_ID("customer_id"),
MODEL_NUMBER("model_number");
String textValue;
Key() {
}
Key(String textValue) {
this.textValue = textValue;
}
String textValue() {
return this.textValue;
}
}
public enum ScreenName {
PLATFORM_APP_LAUNCHER("platform_app_launcher"),
GRANT_PERMISSION_DIALOG_SCREEN("grant_permission_dialog_screen"),
CONFIGURATION_SCREEN("configuration_screen"),
MAIN_SPLASH("main_splash"),
LOGIN_SCREEN("login_screen"),
COLLECTION_SCREEN("collection_screen"),
PHONE_NUMBER_SCREEN("phone_number_screen"),
PHONE_CONF_POPUP("phone_number_confirmation_popup"),
OTP_SCREEN("otp_screen"),
PROFILE_POPUP("profile_popup"),
SOCIAL_MEDIA_LOGIN("social_media_login_screen"),
MAIN_HOME_DASHBOARD("main_home_dashboard"),
MAIN_HOME_NAVIGATION("main_home_navigation"),
PROFILE_SCREEN("profile_screen"),
IMAGE_SELECTION_POPUP("image_selection_popup"),
PHONE_NUMBER_POPUP("phone_number_popup"),
FEEDBACK_SCREEN("feedback_screen"),
NAVIGATION_SCREEN("navigation_screen");
String textValue;
ScreenName(String textValue) {
this.textValue = textValue;
}
String textValue() {
return this.textValue;
}
}
public enum Description {
BACKGROUND_POPUP("background_popup"),
OPEN_PHONE_NUMBER_SCREEN("open_phone_number_screen"),
OPEN_TERMS_AND_CONDITION_SCREEN("open_terms_and_condition"),
OPEN_PHONE_NUMBER_CONFIRMATION_POPUP("open_phone_number_confirmation_popup"),
OPEN_OTP_SCREEN("open_otp_screen"),
PHONE_NUMBER_SCREEN("phone_number_screen"),
OPEN_PROFILE_POPUP("open_profile_popup"),
SOCIAL_MEDIA_LOGIN_SCREEN("social_media_login_screen"),
MAIN_HOME_DASHBOARD("main_home_dashboard"),
OPEN_PROFILE_SCREEN("open_profile_screen"),
OPEN_RECONNECTION_POPUP("open_reconnection_popup"),
OPEN_MAIN_HOME_NAVIGATION("open_main_home_navigation"),
OPEN_IMAGE_SELECTION_POPUP("open_image_selection_popup"),
EDIT_PHONE_NUMBER_POPUP("edit_phone_number_popup"),
OPEN_GALLERY("open_gallery"),
OPEN_CAMERA("open_camera"),
OPEN_CONTACT_SCREEN("open_contact_screen"),
OPEN_SHARE_SCREEN("show_share_screen"),
OPEN_LOGIN_SCREEN("open_login_screen"),
OPEN_HOME_SCREEN("open_home_screen")
;
String textValue;
Description(String textValue) {
this.textValue = textValue;
}
String textValue() {
return this.textValue;
}
}
public enum UiElementName {
SWIPE_LEFT("swipe_left"),
SWIPE_RIGHT("swipe_right"),
SKIP_BUTTON("skip_button"),
NEXT_BUTTON("next_button"),
OK_BUTTON("ok_button"),
CANCEL_BUTTON("cancel_button"),
RESEND_OTP_BUTTON("resend_button"),
GALLERY_BUTTON("gallery_button"),
CATURE_FROM_CAMERA_BUTTON("cature_from_camera_button"),
DONE_BUTTON("done_button"),
COLLECTION_BUTTON("collection_button"),
GALLARY_BUTTON("gallary_button");
String textValue;
UiElementName(String textValue) {
this.textValue = textValue;
}
String textValue() {
return this.textValue;
}
}
}
HuaweiLog.java
Java:
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class HuaweiLog {
private HuaweiEventParams.EventName eventName;
private HashMap<String, String> data = new HashMap<>();
private HashMap<String, ArrayList> testdata = new HashMap<>();
public HuaweiLog() {
}
public HuaweiEventParams.EventName getEventName() {
return eventName;
}
public HuaweiLog setEventName(HuaweiEventParams.EventName eventName) {
this.eventName = eventName;
return this;
}
public HuaweiLog setPreviousScreenName(HuaweiEventParams.ScreenName previousScreenName) {
data.put(HuaweiEventParams.Key.PREVIOUS_SCREEN_NAME.textValue(), previousScreenName.textValue());
return this;
}
public HuaweiLog setDescription(HuaweiEventParams.Description description) {
data.put(HuaweiEventParams.Key.DESCRIPTION.textValue(), description.textValue());
return this;
}
public HuaweiLog setDescription(String description) {
data.put(HuaweiEventParams.Key.DESCRIPTION.textValue(), description);
return this;
}
public HuaweiLog setCustomerId(String cId) {
data.put(HuaweiEventParams.Key.CUSTOMER_ID.textValue(), cId);
return this;
}
public HuaweiLog setCustomerMobileNumber(String mobileNumber) {
data.put(HuaweiEventParams.Key.CUSTOMER_ID.textValue(), mobileNumber);
return this;
}
public HuaweiLog setParentScreenName(HuaweiEventParams.ScreenName parentScreenName) {
data.put(HuaweiEventParams.Key.PARENT_SCREEN_NAME.textValue(), parentScreenName.textValue());
return this;
}
public HuaweiLog setScreenName(HuaweiEventParams.ScreenName screenName) {
data.put(HuaweiEventParams.Key.SCREEN_NAME.textValue(), screenName.textValue());
return this;
}
public HuaweiLog setScreenName(String screenName) {
data.put(HuaweiEventParams.Key.SCREEN_NAME.textValue(), screenName);
return this;
}
public HuaweiLog setUiElementName(String uiElementName) {
data.put(HuaweiEventParams.Key.UI_ELEMENT.textValue(), uiElementName);
return this;
}
public HuaweiLog setUiElementName(HuaweiEventParams.UiElementName uiElementName) {
data.put(HuaweiEventParams.Key.UI_ELEMENT.textValue(), uiElementName.textValue());
return this;
}
public HuaweiLog setKeyAndValue(String key, String value) {
data.put(key, value);
return this;
}
public Bundle toBundle() {
Bundle bundle = new Bundle();
try {
if (data != null && data.size() > 0) {
for (Map.Entry<String, String> entry : data.entrySet()) {
bundle.putString(entry.getKey(), entry.getValue());
Log.d("Huawei",entry.getKey()+" "+ entry.getValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bundle;
}
public HuaweiLog setTestDescription(ArrayList list) {
testdata.put(HuaweiEventParams.Key.DESCRIPTION.textValue(), list);
return this;
}
}
HuaweiAnalyticsClient.java
Java:
import android.content.Context;
import android.util.Log;
import com.huawei.hms.analytics.HiAnalytics;
import com.huawei.hms.analytics.HiAnalyticsInstance;
import com.huawei.hms.analytics.type.ReportPolicy;
import com.shea.pygmycollection.utils.UserDataUtils;
import java.util.HashSet;
import java.util.Set;
public class HuaweiAnalyticsClient {
private static final String TAG = HuaweiAnalyticsClient.class.getSimpleName();
private static HuaweiAnalyticsClient ourInstance;
private static HiAnalyticsInstance mHuaweiAnalyticsClient;
private HuaweiAnalyticsClient() {
}
public static HuaweiAnalyticsClient getInstance() {
if (ourInstance == null) {
ourInstance = new HuaweiAnalyticsClient();
}
return ourInstance;
}
public void initAnalytics(Context context) {
mHuaweiAnalyticsClient = HiAnalytics.getInstance(context);
if (mHuaweiAnalyticsClient == null) {
Log.e(TAG, "Analytics Client could not be initialized.");
return;
}
mHuaweiAnalyticsClient.setAnalyticsEnabled(true);
mHuaweiAnalyticsClient.setUserId("UserId");
mHuaweiAnalyticsClient.setAutoCollectionEnabled(true);
if (UserDataUtils.getUserData(context) != null) {
if (UserDataUtils.getUserId(context) != 0) {
Integer userId = UserDataUtils.getUserId(context);
Log.d(TAG, "initAnalytics is called");
if (userId != null && userId != 0) {
setHuaweiUserId(String.valueOf(userId));
putHuaweiUserProperty(HuaweiUserProperty.KeyName.USER_PHONE_NUMBER, UserDataUtils.getUserPhoneNumber(context));
} else {
setHuaweiUserId("UNKNOWN");
putHuaweiUserProperty(HuaweiUserProperty.KeyName.USER_PHONE_NUMBER, UserDataUtils.getUserPhoneNumber(context));
}
} else {
setHuaweiUserId("UNKNOWN_USER");
putHuaweiUserProperty(HuaweiUserProperty.KeyName.USER_PHONE_NUMBER, UserDataUtils.getUserPhoneNumber(context));
}
}
// Used to report an event upon app switching to the background.
ReportPolicy moveBackgroundPolicy = ReportPolicy.ON_MOVE_BACKGROUND_POLICY;
// Used to report an event at the specified interval.
ReportPolicy scheduledTimePolicy = ReportPolicy.ON_SCHEDULED_TIME_POLICY;
// Set the event reporting interval to 600 seconds.
scheduledTimePolicy.setThreshold(600);
Set<ReportPolicy> reportPolicies = new HashSet<>();
// Add the ON_SCHEDULED_TIME_POLICY and ON_MOVE_BACKGROUND_POLICY policies.
reportPolicies.add(scheduledTimePolicy);
reportPolicies.add(moveBackgroundPolicy);
// Set the ON_MOVE_BACKGROUND_POLICY and ON_SCHEDULED_TIME_POLICY policies.
mHuaweiAnalyticsClient.setReportPolicies(reportPolicies);
}
public void logEvent(HuaweiLog log) {
if (mHuaweiAnalyticsClient == null) {
throw new RuntimeException("HuaweiAnalyticsClient is not initialized. Please call initAnalytics().");
}
try {
mHuaweiAnalyticsClient.onEvent(log.getEventName().textValue(), log.toBundle());
Log.d("Huawei", log.getEventName().textValue());
} catch (Exception e) {
Log.d(TAG, "Huawei analytics failed" + e.getMessage());
}
}
public void putHuaweiUserProperty(HuaweiUserProperty.KeyName propertyKey, String value) {
if (mHuaweiAnalyticsClient == null) {
throw new RuntimeException("HuaweiAnalyticsClient is not initialized. Please call initAnalytics().");
}
try {
mHuaweiAnalyticsClient.setUserProfile(propertyKey.textValue(), value);
} catch (Exception e) {
Log.d(TAG, "Huawei analytics failed", e);
}
}
public void setHuaweiUserId(String userId) {
if (mHuaweiAnalyticsClient == null) {
throw new RuntimeException("HuaweiAnalyticsClient is not initialized. Please call initAnalytics().");
}
if (userId == null) {
mHuaweiAnalyticsClient.setUserId(null);
return;
}
mHuaweiAnalyticsClient.setUserId(userId);
}
}
AnalyticsUtils.java
Java:
import android.util.Log;
public class AnalyticUtils {
private static final String TAG = AnalyticUtils.class.getSimpleName();
public static void logHuaweiAnalyticEvent(HuaweiLog huaweiLog) {
try {
HuaweiAnalyticsClient.getInstance().logEvent(huaweiLog);
Log.d(TAG, "Huawei analytics " + huaweiLog.toString());
} catch (Exception e) {
Log.d(TAG, "Huawei analytics failed");
}
}
}
Now log the events in activity/fragments/dialog
Java:
AnalyticUtils.logHuaweiAnalyticEvent(new HuaweiLog()
.setScreenName(HuaweiEventParams.ScreenName.MAIN_SPLASH)
.setDescription(HuaweiEventParams.Description.OPEN_SHARE_SCREEN)
.setEventName(HuaweiEventParams.EventName.OPEN)
.setUiElementName(HuaweiEventParams.UiElementName.GALLARY_BUTTON)
);
Java:
AnalyticUtils.logHuaweiAnalyticEvent(new HuaweiLog()
.setScreenName(HuaweiEventParams.ScreenName.COLLECTION_SCREEN)
.setDescription(HuaweiEventParams.Description.OPEN_HOME_SCREEN)
.setEventName(HuaweiEventParams.EventName.TAP)
.setUiElementName(HuaweiEventParams.UiElementName.COLLECTION_BUTTON)
);
Result​
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Tips and Tricks​
Make sure you added agconnect-service.json file.
Add internet permission in AndroidManifest.xml
Add the below code to download the HMS core apk
XML:
<application ...>
<meta-data
android:name="com.huawei.hms.client.channel.androidMarket"
android:value="false" />
...
</application>
​Conclusion​
In this article, we have learnt what is analytics, why to use analytics kit, where to use, how to use, how to integrate HMS analytics kit and how to add custom events.
Reference​
Huawei Analytics
Thanks for sharing!!!

Categories

Resources