How to know more about the client with Huawei Push Kit? - Huawei Developers

{
"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 provided by Huawei for developers. It establishes a communication channel between the cloud and devices. By using Huawei Push Kit, developers can send the latest messages to users. This helps developers maintain closer ties with users and increases user awareness and activity. User can tap the message displayed in the notification bar of the device and can open the corresponding app and view more details. Huawei Push Kit is already available more than 200+ countries and regions. It offers the capacity of sending 10 million messages per second from the server, delivering 99% of them and providing real time push reports ultimately helping improve the DAU of your apps.
Today in this article we are going to see how to integrate HMS core Push kit into your apps.
Prerequisite
1) Must have a Huawei Developer Account.
2) Must have a Huawei phone with HMS 4.0.0.300 or later
3) Must have a laptop or desktop with Android Studio , Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.
Things Need To Be Done
1) First we need to create a project in android studio.
2) Get the SHA Key. For getting the SHA key we can refer to this article.
3) Create an app in the Huawei app gallery connect.
4) Enable push kit setting in Manage APIs section.
5) Provide the SHA Key in App Information Section.
6) Provide storage location.
7) Under Develop tab, go to Growing > Push and select service status Enable.
8) After completing all the above points we need to download the agconnect-services.json from App Information Section. Copy and paste the Json file in the app folder of the android project.
9) Copy and paste the below maven url inside the repositories of buildscript and allprojects ( project build.gradle file )
maven { url 'http://developer.huawei.com/repo/' }
10) Copy and paste the below plugin in the app build.gradle file
apply plugin: 'com.huawei.agconnect'
11) Now Sync the gradle.
Let’s Code
Service Class
First we need to configure app AndroidManifest.xml file. Before we go ahead and providing configuration to the AndroidManifest.xml file, we need to create a Push service class which will extend HmsMessageService class.
This service class will provide us with two callback methods i.e. onNewToken() and onMessageReceived(). In onNewToken() method we will receive the token here and onMessageReceived() method we will receive the data messages sent by Huawei Push.
Code:
public class MyPushService extends HmsMessageService {
private static final String TAG = "PushDemoLog";
@Override
public void onNewToken(String token) {
super.onNewToken(token);
Log.i(TAG, "receive token:" + token);
}
@Override
public void onMessageReceived(RemoteMessage message) {
super.onMessageReceived(message);
Log.i(TAG, "getCollapseKey: " + message.getCollapseKey()
+ "\n getData: " + message.getData()
+ "\n getFrom: " + message.getFrom()
+ "\n getTo: " + message.getTo()
+ "\n getMessageId: " + message.getMessageId()
+ "\n getSendTime: " + message.getSentTime()
+ "\n getMessageType: " + message.getMessageType()
+ "\n getTtl: " + message.getTtl());
RemoteMessage.Notification notification = message.getNotification();
if (notification != null) {
Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
+ "\n getTitle: " + notification.getTitle()
+ "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
+ "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
+ "\n getBody: " + notification.getBody()
+ "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
+ "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
+ "\n getIcon: " + notification.getIcon()
+ "\n getSound: " + notification.getSound()
+ "\n getTag: " + notification.getTag()
+ "\n getColor: " + notification.getColor()
+ "\n getClickAction: " + notification.getClickAction()
+ "\n getChannelId: " + notification.getChannelId()
+ "\n getLink: " + notification.getLink()
+ "\n getNotifyId: " + notification.getNotifyId());
}
}
}
This service need to be mention or configure in the AndroidManifest.xml file. Copy and paste the below code after </activity> tag and before </application> tag.
Code:
<service
android:name=".MyPushService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
To get the token from the HMS Push kit we need to write the following code in the Activity class (it could be any activity class example MainActivity).
Code:
private void getToken(){
new Thread() {
@Override
public void run() {
try {
String appId = AGConnectServicesConfig.fromContext(MainActivity.this).getString("client/app_id");
pushtoken = HmsInstanceId.getInstance(MainActivity.this).getToken(appId, "HCM");
if(!TextUtils.isEmpty(pushtoken)) {
Log.i(TAG, "get token:" + pushtoken);
showLog(pushtoken);
}
} catch (Exception e) {
Log.i(TAG,"getToken failed, " + e);
}
}
}.start();
}
On the log we will be able to see the token as shown below
Turn Off / On Notification
Suppose user doesn’t want any notification from your app, we can achieve this functionality by simply calling HmsMessaging class. This class contain two methods turnOnPush() and turnOffPush(). Below you will find the code to turn off / on notification. By default the notification message is enable.
Code:
private void turnOnNotification(){
HmsMessaging.getInstance(this).turnOnPush().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
Log.i(TAG, "turnOnPush Complete");
} else {
Log.e(TAG, "turnOnPush failed: ret=" + task.getException().getMessage());
}
}
});
}
private void turnOffNotification(){
HmsMessaging.getInstance(this).turnOffPush().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
Log.i(TAG, "turnOnPush Complete");
} else {
Log.e(TAG, "turnOnPush failed: ret=" + task.getException().getMessage());
}
}
});
}
Sending Notification
To send notification message we need to go to AGC and select My apps. Under My apps we will find the app which we have created to get notification. Select the app go to Operate > Promotion > Push. Select Add Notification button. Provide details as shown below and click Test effect button which will ask for token. Put the token and select okay.
We have a second part of this article i.e. HMS PUSH KIT SERVER SIDE ( PART 2 ). I would recommend you to go for it. It will help you to have a clear picture of HMS Push Kit.
That’s it
For more information like this, you can visit https://forums.developer.huawei.com/forumPortal/en/home

Related

Huawei Flight Booking Application (Crash Service and Push kit) – Part 3

Introduction
Flight booking app allows user to search and book flight. In this article, we will integrate app messaging and analytics into demo flight booking application.
For prerequisite, permission and set up, refer to part 1.
Usecase
1. We will integrate Huawei Crash analytics to monitors and captures your crashes, also it analyzes them, and then groups into manageable issues. And it does this through lightweight SDK that won’t bloat your app. You can integrate Huawei crash analytics SDK with a single line of code before you publish.
2. We will send push notification which establishes communication between cloud and devices. Using HMS push kit, developers can send message to user.
Crash Analytics
1. In order to use Crash service, we need to integrate Analytics kit by adding following code in app-level build.gradle.
Code:
implementation 'com.huawei.hms:hianalytics:5.0.1.301'
2. Enable Analytics in ACG. Refer Service Enabling.
3. Integrate Crash SDK by adding following code in app-level build.gradle.
Code:
implementation 'com.huawei.agconnect:agconnect-crash:1.4.1.300'
4. In onCreate() of MainActivity class, enable crash analytics.
Code:
AGConnectCrash.getInstance().enableCrashCollection(true);
5. To trigger a crash
Code:
AGConnectCrash.getInstance().testIt(this);
Note: Please comment the above code before releasing or publishing the app. It deliberately causes app to crash and just used for testing HMS crash service.
6. To monitor a crash report inApp Gallery Connect, select your app from MyProjects. Select Quality -> Crash on left panel of the screen. Click on Problems.
{
"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"
}
7. Setting screen has been designed to enable crash service.
Push Kit
1. Enable push kit in AGC. Refer Service Enabling.
2. Integrate Push kit SDK by adding following code in app-level build.gradle.
Code:
implementation 'com.huawei.hms:push:5.0.1.300'
3. Call getToken() method in onCreate() of MainActivity class. Generated token will be used later in AGC to send notification.
Code:
private void getToken() {
new Thread() {
@Override
public void run() {
try {
// read from agconnect-services.json
String appId = AGConnectServicesConfig.fromContext(MainActivity.this).getString("client/app_id");
String token = HmsInstanceId.getInstance(MainActivity.this).getToken(appId, "HCM");
Log.i(TAG, "get token:" + token);
if(!TextUtils.isEmpty(token)) {
sendRegTokenToServer(token);
}
} catch (ApiException e) {
Log.e(TAG, "get token failed, " + e);
}
}
}.start();
}
private void sendRegTokenToServer(String token) {
Log.i(TAG, "sending token to server. token:" + token);
}
4. To deregister the token.
Code:
new Thread() {
@Override
public void run() {
try {
// read from agconnect-services.json
String appId = AGConnectServicesConfig.fromContext(this).getString("client/app_id");
HmsInstanceId.getInstance(this).deleteToken(appId, "HCM");
Log.i(TAG, "deleteToken success.");
} catch (ApiException e) {
Log.e(TAG, "deleteToken failed." + e);
}
}
}.start();
5. Create a Service which extends HmsMessageService class. Declare it in Manifest.
Code:
<service
android:name=".service.FLightHmsMessageService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT"/>
</intent-filter>
</service>
6. Override onMessageReceivedMethod() to obtain the message data.
Code:
@Override
public void onMessageReceived(RemoteMessage message) {
super.onMessageReceived(message);
Log.i(TAG, "getCollapseKey: " + message.getCollapseKey()
+ "\n getData: " + message.getData()
+ "\n getFrom: " + message.getFrom()
+ "\n getTo: " + message.getTo()
+ "\n getMessageId: " + message.getMessageId()
+ "\n getSendTime: " + message.getSentTime()
+ "\n getMessageType: " + message.getMessageType()
+ "\n getTtl: " + message.getTtl());
RemoteMessage.Notification notification = message.getNotification();
if (notification != null) {
Log.i(TAG, "\n getImageUrl: " + notification.getImageUrl()
+ "\n getTitle: " + notification.getTitle()
+ "\n getTitleLocalizationKey: " + notification.getTitleLocalizationKey()
+ "\n getTitleLocalizationArgs: " + Arrays.toString(notification.getTitleLocalizationArgs())
+ "\n getBody: " + notification.getBody()
+ "\n getBodyLocalizationKey: " + notification.getBodyLocalizationKey()
+ "\n getBodyLocalizationArgs: " + Arrays.toString(notification.getBodyLocalizationArgs())
+ "\n getIcon: " + notification.getIcon()
+ "\n getSound: " + notification.getSound()
+ "\n getTag: " + notification.getTag()
+ "\n getColor: " + notification.getColor()
+ "\n getClickAction: " + notification.getClickAction()
+ "\n getChannelId: " + notification.getChannelId()
+ "\n getLink: " + notification.getLink()
+ "\n getNotifyId: " + notification.getNotifyId());
}
}
7. Log in to AGC, select your project and navigate to Growing -> Push kit. And compose the message for notification. Provide the token which was earlier generated from getToken() method.
Image
Conclusion:
In this article, we learnt how to integrate Huawei crash service and HMS push kit to in application.
For detailed guide, refer to
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/service-introduction-0000001050040060
https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-crash-introduction

How to Integrate HUAWEI Drive Kit

More information like this, you can visit HUAWEI Developer Forum​
Hello everyone, in this article we will create an Android application using the capabilities of HUAWEI Drive Kit that will allow users to manage and edit files in HUAWEI Drive, as well as store photos, drawings, designs, recordings and videos.
Why should we use HUAWEI Drive Kit?
With HUAWEI Drive Kit, you can let your users store data on the cloud quick and easy. Users can upload, download, synchronize, and view images, videos, and documents whenever and wherever they want.
There are 3 main functions provided by HUAWEI Drive Kit.
User file management: Includes file search, comment, and reply in addition to basic functions.
App data management: Supports app data storage and restoration.
Cross-platform capability: Provides RESTful APIs to support app access from non-Android devices.
Integration Preparations
Before you get started, you must first register as a HUAWEI developer and verify your identity on the HUAWEI Developer website. For more details, please refer to Register a HUAWEI ID.
Software Requirements
Java JDK installation package
Android SDK package
Android Studio 3.X
HMS Core (APK) 3.X or later
Supported Locations
To see all supported locations, please refer to HUAWEI Drive Kit Supported Locations
Integrating HMS Core SDK
To integrate HMS Core SDK in your application and learn creating a new project on AppGallery Connect, follow this great guide: https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98
Keep in mind: Users need to sign in with their HUAWEI ID before they can use the functions provided by HUAWEI Drive Kit. If the user has not signed in with a HUAWEI ID, the HMS Core SDK will prompt the user to sign in first.
Implementation
Code:
implementation 'com.huawei.hms:drive:5.0.0.301'
implementation 'com.huawei.hms:hwid:5.0.1.301'
Now that we’re ready to implement our methods, let’s see how they work.
Signing In with a HUAWEI ID
To implement the sign-in function through the HMS Core SDK, you will need to set the Drive scope for obtaining the permission to access Drive APIs.
Each Drive scope corresponds to a certain type of permissions. You may apply for the permissions as needed. For details about the corresponding APIs, please refer to HUAWEI Account Kit Development Guide.
Code:
private void driveSignIn() {
List<Scope> scopeList = new ArrayList<>();
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE));
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_APPDATA));
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_FILE));
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA));
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA_READONLY));
scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_READONLY));
scopeList.add(HuaweiIdAuthAPIManager.HUAWEIID_BASE_SCOPE);
HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setAccessToken()
.setIdToken()
.setScopeList(scopeList)
.createParams();
HuaweiIdAuthService authService = HuaweiIdAuthManager.getService(this, authParams);
startActivityForResult(authService.getSignInIntent(), REQUEST_SIGN_IN_LOGIN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_SIGN_IN_LOGIN) {
Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
AuthHuaweiId authHuaweiId = authHuaweiIdTask.getResult();
mAccessToken = authHuaweiId.getAccessToken();
mUnionId = authHuaweiId.getUnionId();
int returnCode = init(mUnionId, mAccessToken, refreshAccessToken);
if (returnCode == DriveCode.SUCCESS) {
Log.d(TAG, "onActivityResult: driveSignIn success");
} else {
Log.d(TAG, "onActivityResult: driveSignIn failed");
}
} else {
Log.d(TAG, "onActivityResult, signIn failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
}
Handling the Permissions
Add the read and write permissions for the phone storage to AndroidManifest.xml
Code:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_MEDIA_STORAGE"
tools:ignore="ProtectedPermissions" />
Add the permissions to request in MainActivity.java.
Code:
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
};
Request the permissions in the onCreate method.
Code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(PERMISSIONS_STORAGE, 1);
}
Create a Folder and Upload a File
Now that we handled necessary permissions, let’s upload some files!
Create a folder in the root directory of Drive, and upload the file in the designated directory.
Keep in mind: the code below contains global variables and functions, you can download the sample code from the link at the end of the article to view their meanings.
Code:
private void uploadFiles() {
new Thread(new Runnable() {
@Override
public void run() {
try {
if (mAccessToken == null) {
Log.d(TAG, "need to sign in first");
return;
}
if (StringUtils.isNullOrEmpty(et_uploadFileName.getText().toString())) {
Log.d(TAG, "file name is required to upload");
return;
}
String path = getExternalFilesDir(null).getAbsolutePath()
+ "/" + et_uploadFileName.getText();
Log.d(TAG, "run: " + path);
java.io.File fileObj = new java.io.File(path);
if (!fileObj.exists()) {
Log.d(TAG, "file does not exists");
return;
}
Drive drive = buildDrive();
Map<String, String> appProperties = new HashMap<>();
appProperties.put("appProperties", "property");
String dirName = "Uploads";
File file = new File();
file.setFileName(dirName)
.setAppSettings(appProperties)
.setMimeType("application/vnd.huawei-apps.folder");
directoryCreated = drive.files().create(file).execute();
// Upload the file
File fileToUpload = new File()
.setFileName(fileObj.getName())
.setMimeType(mimeType(fileObj))
.setParentFolder(Collections.singletonList(directoryCreated.getId()));
Drive.Files.Create request = drive.files()
.create(fileToUpload, new FileContent(mimeType(fileObj), fileObj));
fileUploaded = request.execute();
Log.d(TAG, "upload success");
} catch (Exception e) {
Log.d(TAG, "upload error " + e.toString());
}
}
}).start();
}
If applicationData is selected, the operation will be performed on the app data folder. The app data folder is invisible to users and is used to store app-specific data.
After the upload is done, the users can view the file by going to Files > HUAWEI Drive.
{
"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"
}
Query File Details
With this method we can get the details of a file in Drive. Below, we get the id, file name and size information.
Code:
private void queryFiles() {
new Thread(new Runnable() {
@Override
public void run() {
try {
if (mAccessToken == null) {
Log.d(TAG, "need to sign in first");
return;
}
String containers = "";
String queryFile = "fileName = '" + et_searchFileName.getText()
+ "' and mimeType != 'application/vnd.huawei-apps.folder'";
if (cb_isApplicationData.isChecked()) {
containers = "applicationData";
queryFile = "'applicationData' in parentFolder and ".concat(queryFile);
}
Drive drive = buildDrive();
Drive.Files.List request = drive.files().list();
FileList files;
while (true) {
files = request
.setQueryParam(queryFile)
.setPageSize(10)
.setOrderBy("fileName")
.setFields("category,nextCursor,files(id,fileName,size)")
.setContainers(containers)
.execute();
if (files == null || files.getFiles().size() > 0) {
break;
}
if (!StringUtils.isNullOrEmpty(files.getNextCursor())) {
request.setCursor(files.getNextCursor());
} else {
break;
}
}
String text = "";
if (files != null && files.getFiles().size() > 0) {
fileSearched = files.getFiles().get(0);
text = fileSearched.toString();
} else {
text = "empty";
}
final String finalText = text;
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
tv_queryResult.setText(finalText);
}
});
Log.d(TAG, "query success");
} catch (Exception e) {
Log.d(TAG, "query error " + e.toString());
}
}
}).start();
}
Download Files
We can also download files from Drive. Just query the file (notice the fileSearched global variable above) and download with Drive.Files.Get request.
This is not the end. For full content, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202357120930420217&fid=0101187876626530001
Is there any restriction on type of files which can be uploaded and while uploading are there any security measures taken like encryption of my data ?
Nice and useful article
DOes Huawei drive kit work in India?

Huawei In App Purchase integration in Unity app using Unity UDP Package

The purpose of this article is how to use Huawei in App Purchase integration in Unity app using Unity UDP. Here we are going to create a sample project in Unity with the help of UDP Package.
In this section, following are covered:
1. How to create new project in UDP Console?
2. How to Import UDP Package?
3. How to link UDP Console Project in unity editor and how to create IAP Products?
4. How to Implement UDP IAP in Client Side?
5. How to Configure IAP in Huawei AGC Console?
6. How to Link UDP Console with Huawei AGC Console?
1. How to create new project in UDP Console?
a) Navigate to below URL and click to sign in to access UDP console
https://distribute.dashboard.unity.com/
b) To create new game, navigate to My Games > Create New Game (You can create a game on the UDP console first, and later link it to an actual UDP project in unity)
{
"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"
}
c) Enter required fields in Edit Game Information and click SAVE.
d) Copy the client id from the Integration Information panel of the Game Info section, in the UDP console.
2. How to Import UDP Package?
a) Navigate to the unity editor and import Unity Distribution Portal (UDP) from asset store.
b) Once it is imported you can see the sample IAP Client side code which contains all the basic modules like initialization, purchase, query, consume etc.
3. How to link UDP Console Project in unity editor and How to create IAP Products?
a) Now we need to link UDP project with Unity (Window > Unity Distribution Portal > Settings). Paste the client id which you copied from UDP console and link it to UDP Client.
b) Once your Unity project is linked to a UDP client, the UDP Settings inspector loads more settings (like IAP Catalog, UDP Sandbox test account, push, pull).
c) Now you can add and define IAP products in the IAP Catalog section of the UDP Settings. The Pull and Push buttons in the top section of the UDP Settings window sync your IAP Catalog with the UDP server. You can add sandbox test account in UDP Sandbox Test Accounts.
d) Once IAP details are configured and pushed. You can see the IAP details in Udp Console.
4. How to Implement UDP IAP in Client Side?
a) Now it’s time to implement client side logic.
Please refer the below link and sample code in Unity Editor (Projects > Assets > UDP > Sample > Scripts > UDPSampleScript.cs) which I referred for the implementation.
URL: https://docs.unity3d.com/Packages/[email protected]/manual/Implementing-UDP-IAP-on-the-client-side.html
b) Now create buttons and script file in unity editor.
c) Add the below code to the Script and link the above buttons to the correct On Click listeners in Script.
Code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.UDP;
public class NewBehaviourScript : MonoBehaviour
{
int n;
public Text myText1;
InitListener m_InitListener;
PurchaseListener m_PurchaseListener;
private static bool m_ConsumeOnPurchase;
private static bool m_ConsumeOnQuery;
private static bool m_Initialized;
public void OnInit()
{
Debug.Log("Oninitialize");
m_InitListener = new InitListener();
m_PurchaseListener = new PurchaseListener();
m_Initialized = false;
StoreService.Initialize(m_InitListener);
}
public void OnPurchase()
{
if (!m_Initialized)
{
Debug.Log("Please Initialize first");
return;
}
string prodcutId = "test_1";
Debug.Log("Buy button is clicked.");
m_ConsumeOnPurchase = false;
Debug.Log("test_1 will be bought");
StoreService.Purchase(prodcutId, "payload", m_PurchaseListener);
}
public void OnPurchaseNonConsumable()
{
if (!m_Initialized)
{
Debug.Log("Please Initialize first");
return;
}
string prodcutId = "test_2";
Debug.Log("Buy button is clicked.");
m_ConsumeOnPurchase = false;
Debug.Log("test_2 will be bought");
StoreService.Purchase(prodcutId, "payload", m_PurchaseListener);
}
public void OnBuyConsume()
{
if (!m_Initialized)
{
Debug.Log("Please Initialize first");
return;
}
string prodcutId = "test_1";
Debug.Log("Buy&Consume button is clicked.");
m_ConsumeOnPurchase = true;
StoreService.Purchase(prodcutId, "payload2", m_PurchaseListener);
}
List<string> productIds = new List<string> { "test_1", "test_2" };
public void OnQueryButton()
{
if (!m_Initialized)
{
Debug.Log("Please Initialize first");
return;
}
m_ConsumeOnQuery = false;
Debug.Log("Query button is clicked.");
StoreService.QueryInventory(productIds, m_PurchaseListener);
}
public void OnQueryConsumeButton()
{
if (!m_Initialized)
{
Debug.Log("Please Initialize first");
return;
}
m_ConsumeOnQuery = true;
Debug.Log("QueryConsume button is clicked.");
StoreService.QueryInventory(productIds, m_PurchaseListener);
}
public class InitListener : IInitListener
{
public void OnInitialized(UserInfo userInfo)
{
Debug.Log("[Game]On Initialized suceeded");
m_Initialized = true;
}
public void OnInitializeFailed(string message)
{
Debug.Log("[Game]OnInitializeFailed: " + message);
}
}
public class PurchaseListener : IPurchaseListener
{
public void OnPurchase(PurchaseInfo purchaseInfo)
{
string message = string.Format(
"[Game] Purchase Succeeded, productId: {0}, cpOrderId: {1}, developerPayload: {2}, storeJson: {3}",
purchaseInfo.ProductId, purchaseInfo.GameOrderId, purchaseInfo.DeveloperPayload,
purchaseInfo.StorePurchaseJsonString);
Debug.Log(message);
// Show(message);
/*
* If the product is consumable, consume it and deliver the product in OnPurchaseConsume().
* Otherwise, deliver the product here.
*/
if (m_ConsumeOnPurchase)
{
Debug.Log("Consuming");
StoreService.ConsumePurchase(purchaseInfo, this);
}
}
public void OnPurchaseFailed(string message, PurchaseInfo purchaseInfo)
{
Debug.Log("Purchase Failed: " + message);
}
public void OnPurchaseRepeated(string productCode)
{
throw new System.NotImplementedException();
}
public void OnPurchaseConsume(PurchaseInfo purchaseInfo)
{
Debug.Log("Consume success: " + purchaseInfo.ProductId);
}
public void OnPurchaseConsumeFailed(string message, PurchaseInfo purchaseInfo)
{
Debug.Log("Consume Failed: " + message);
}
public void OnQueryInventory(Inventory inventory)
{
Debug.Log("OnQueryInventory");
Debug.Log("[Game] Product List: ");
string message = "Product List: \n";
foreach (KeyValuePair<string, ProductInfo> productInfo in inventory.GetProductDictionary())
{
Debug.Log("[Game] Returned product: " + productInfo.Key + " " + productInfo.Value.ProductId);
message += string.Format("{0}:\n" +
"\tTitle: {1}\n" +
"\tDescription: {2}\n" +
"\tConsumable: {3}\n" +
"\tPrice: {4}\n" +
"\tCurrency: {5}\n" +
"\tPriceAmountMicros: {6}\n" +
"\tItemType: {7}\n",
productInfo.Key,
productInfo.Value.Title,
productInfo.Value.Description,
productInfo.Value.Consumable,
productInfo.Value.Price,
productInfo.Value.Currency,
productInfo.Value.PriceAmountMicros,
productInfo.Value.ItemType
);
}
message += "\nPurchase List: \n";
foreach (KeyValuePair<string, PurchaseInfo> purchaseInfo in inventory.GetPurchaseDictionary())
{
Debug.Log("[Game] Returned purchase: " + purchaseInfo.Key);
message += string.Format("{0}\n", purchaseInfo.Value.ProductId);
}
if (m_ConsumeOnQuery)
{
StoreService.ConsumePurchase(inventory.GetPurchaseList(), this);
}
}
public void OnQueryInventoryFailed(string message)
{
Debug.Log("OnQueryInventory Failed: " + message);
}
}
}
For more information, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201366685963750355&fid=0101187876626530001

Expert: Courier App MVVM Jetpack (HMS Push Kit) in Android using Kotlin- Part-2

Overview
In this article, I will create a Courier android application using Kotlin in which I will integrate HMS Core kits such as HMS Account and AuthService Kit.
We have integrated HMS Account and AuthService Kit in part-1 of this series. Kindly go through the link below-
// pls add part-1 link
App will make use of android MVVM clean architecture using Jetpack components such as DataBinding, AndroidViewModel, Observer, LiveData and much more.
In this article, we are going to implement DataBinding using Observable pattern.
Huawei Push Kit Introduction
Push Kit is a messaging service provided by Huawei for developers. Push Kit establishes a messaging channel from the cloud to devices. By integrating HUAWEI Push Kit, developers can send messages to apps on users’ devices in real time. Push Kit helps developers rapidly to reach the target audience. Push notification can be sent to everyone or to a specific person individually. For send notification, user’s token is required. You can send messages to a device group or specific user. Push Kit has two different notification type. Text only style (Shows longer text messages) and big picture style (Shows large text and image messages).
Prerequisite
Huawei Phone EMUI 3.0 or later.
Non-Huawei phones Android 4.4 or later (API level 19 or higher).
HMS Core APK 4.0.0.300 or later
Android Studio
AppGallery Account
App Gallery Integration process
Sign In and Create or Choose a project on AppGallery Connect portal.
Navigate to Project settings and download the configuration file.
Navigate to General Information, and then provide Data Storage location.
App Development
Add Required Dependencies:
Launch Android studio and create a new project. Once the project is ready.
Navigate to the Gradle scripts folder and open build.gradle (module: app).
In the same build.gradle file, add the lifecycle library to your dependencies. This library helps to connect the UI to a ViewModel and LiveData.
Add following dependency for HMS Push Kits
Navigate to the Gradle scripts folder and open build.gradle (project: app).
Code Implementation
Created following package model, push, viewmodel.
Model: In your primary folder, create a new package and name it model.
Java:
package com.hms.corrierapp.push
import android.util.Log
import com.huawei.hms.push.HmsMessageService
import com.huawei.hms.push.RemoteMessage
import java.util.*
class PushService : HmsMessageService() {
private val TAG = "PushService"
override fun onNewToken(token: String?) {
super.onNewToken(token)
Log.i(TAG, "Receive Token : $token");
}
override fun onMessageReceived(message: RemoteMessage?) {
super.onMessageReceived(message)
Log.i(
TAG, "getCollapseKey: " + message?.collapseKey
+ "\n getData: " + message?.data
+ "\n getFrom: " + message?.from
+ "\n getTo: " + message?.to
+ "\n getMessageId: " + message?.messageId
+ "\n getSendTime: " + message?.sentTime
+ "\n getMessageType: " + message?.messageType
+ "\n getTtl: " + message?.ttl
)
val notification: RemoteMessage.Notification = message!!.notification
Log.i(
TAG, "\n getImageUrl: " + notification.imageUrl
+ "\n getTitle: " + notification.title
+ "\n getTitleLocalizationKey: " + notification.titleLocalizationKey
+ "\n getTitleLocalizationArgs: " + Arrays.toString(notification.titleLocalizationArgs)
+ "\n getBody: " + notification.body
+ "\n getBodyLocalizationKey: " + notification.bodyLocalizationKey
+ "\n getBodyLocalizationArgs: " + Arrays.toString(notification.bodyLocalizationArgs)
+ "\n getIcon: " + notification.icon
+ "\n getSound: " + notification.sound
+ "\n getTag: " + notification.tag
+ "\n getColor: " + notification.color
+ "\n getClickAction: " + notification.clickAction
+ "\n getChannelId: " + notification.channelId
+ "\n getLink: " + notification.link
+ "\n getNotifyId: " + notification.notifyId
)
}
}
Java:
package com.hms.corrierapp.push
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
class AccessTokenClient {
companion object{
private const val TIMEOUT: Long = 500000
fun getClient() : Retrofit {
val logginInterceptor = HttpLoggingInterceptor()
logginInterceptor.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT,TimeUnit.MICROSECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(logginInterceptor).build()
return Retrofit.Builder()
.baseUrl("https://oauth-login.cloud.huawei.com/").client(client)
.addConverterFactory(GsonConverterFactory.create()).build()
}
}
}
Java:
package com.hms.corrierapp.push
import retrofit2.Call
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.Headers
import retrofit2.http.POST
interface AccessTokenInterface {
@FormUrlEncoded
@Headers("Content-Type:application/x-www-form-urlencoded; charset=UTF-8")
@POST("oauth2/v3/token")
fun createAccessToken(
@Field("grant_type") grant_type : String,
@Field("client_secret") client_secret : String,
@Field("client_id") client_id : String) : Call<AccessTokenModel>
}
App Build 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
Identity Kit displays the HUAWEI ID registration or sign-in page first. The user can use the functions provided by Identity Kit only after signing in using a registered HUAWEI ID.
Push Kit supports cross-region messaging, but the messaging performance may be affected. To minimize cross-region messaging, it is recommended that you deploy servers in regions where users gather.
Conclusion
In this article, we have learned how to integrate Huawei ID and Push Kit in Android application. After completely read this article user can easily implement Huawei ID and Client Side Push Notification in the Courier android application using Kotlin.
Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.
References
HMS Docs:
https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870
Document
developer.huawei.com
Push Kit Training Video:
https://developer.huawei.com/consumer/en/training/course/video/101583005582480166

Practice on Pushing Messages to Devices of Different Manufacturers

Push messaging, with the proliferation of mobile Internet, has become a very effective way for mobile apps to achieve business success. It improves user engagement and stickiness by allowing developers to send messages to a wide range of users in a wide range of scenarios: taking the subway or bus, having a meal in a restaurant, having a chat... you name it. No matter what the scenario is, a push message is always a great helper for you to directly "talk" to your users, and for your users to know something informative.
Such great benefits brought by push messages, however, can be dampened by a challenge: the variety of mobile phone manufacturers. This is because usually each manufacturer has their own push messaging channels, which increases the difficulty for uniformly sending your app's push messages to mobile phones of different manufacturers. Of course there is an easy solution for this: sending your push messages to mobile phones of only one manufacturer, but this can limit your user base and prevent you from obtaining your desired messaging effects.
Then this well explains why we developers usually need to find a solution for our apps to be able to push their messages to devices of different brands.
I don't know about you, but the solution I found for my app is HMS Core Push Kit. Going on, I will demonstrate how I have integrated this kit and used its ability to aggregate third-party push messaging channels to implement push messaging on mobile phones made by different manufacturers, expecting greater user engagement and stickiness. Let's move on to the implementation.
Preparations​Before integrating the SDK, make the following preparations:
1. Sign in to the push messaging platform of a specific manufacturer, create a project and app on the platform, and save the JSON key file of the project. (The requirements may vary depending on the manufacturer, so refer to the specific manufacturer's documentation to learn about their requirements.)
2. Configure app information in AppGallery Connet, but use the following build dependency instead when configuring the build dependencies:
Code:
dependencies {
implementation 'com.huawei.hms:push-fcm:6.3.0.304'
}
3. On the platform mentioned in the previous step, click My projects, find the app in the project, and go to Grow > Push Kit > Settings. On the page displayed, click Enable next to Configure other Android-based push, and then copy the key in the saved JSON key file and paste it in the Authentication parameters text box.
{
"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 Procedure​Now, let's go through the development procedure.
1. Disable the automatic initialization of the SDK.
To do so, open the AndroidManifest.xml file, and add the <meta-data> element to the <application> element. Note that in the element, the name parameter has a fixed value of push_kit_auto_init_enabled. As for the value parameter, you can set it to false, indicating that the automatic initialization is disabled.
Code:
<manifest ...>
...
<application ...>
<meta-data
android:name="push_kit_auto_init_enabled"
android:value="false"/>
...
</application>
...
</manifest>
2. Initialize the push capability in either of the following ways:
Set value corresponding to push_kit_proxy_init_enabled in the <meta-data> element to true.
Code:
<application>
<meta-data
android:name="push_kit_proxy_init_enabled"
android:value="true" />
</application>
Explicitly call FcmPushProxy.init in the onCreate method of the Application class.
3. Call the getToken method to apply for a token.
Code:
private void getToken() {
// Create a thread.
new Thread() {
@Override
public void run() {
try {
// Obtain the app ID from the agconnect-services.json file.
String appId = "your APP_ID";
// Set tokenScope to HCM.
String tokenScope = "HCM";
String token = HmsInstanceId.getInstance(MainActivity.this).getToken(appId, tokenScope);
Log.i(TAG, "get token: " + token);
// Check whether the token is empty.
if(!TextUtils.isEmpty(token)) {
sendRegTokenToServer(token);
}
} catch (ApiException e) {
Log.e(TAG, "get token failed, " + e);
}
}
}.start();
}
private void sendRegTokenToServer(String token) {
Log.i(TAG, "sending token to server. token:" + token);
}
4. Override the onNewToken method.
After the SDK is integrated and initialized, the getToken method will not return a token. Instead, you'll need to obtain a token by using the onNewToken method.
Code:
@Override
public void onNewToken(String token, Bundle bundle) {
Log.i(TAG, "onSubjectToken called, token:" + token );
}
5. Override the onTokenError method.
This method will be called if the token fails to be obtained.
Code:
@Override
public void onTokenError(Exception e, Bundle bundle) {
int errCode = ((BaseException) e).getErrorCode();
String errInfo = e.getMessage();
Log.i(TAG, "onTokenError called, errCode:" + errCode + ",errInfo=" + errInfo );
}
6. Override the onMessageReceived method to receive data messages.
Code:
@Override
public void onMessageReceived(RemoteMessage message) {
Log.i(TAG, "onMessageReceived is called");
// Check whether the message is empty.
if (message == null) {
Log.e(TAG, "Received message entity is null!");
return;
}
// Obtain the message content.
Log.i(TAG, "get Data: " + message.getData()
+ "\n getFrom: " + message.getFrom()
+ "\n getTo: " + message.getTo()
+ "\n getMessageId: " + message.getMessageId()
+ "\n getSentTime: " + message.getSentTime()
+ "\n getDataMap: " + message.getDataOfMap()
+ "\n getMessageType: " + message.getMessageType()
+ "\n getTtl: " + message.getTtl()
+ "\n getToken: " + message.getToken());
Boolean judgeWhetherIn10s = false;
// Create a job to process a message if the message is not processed within 10 seconds.
if (judgeWhetherIn10s) {
startWorkManagerJob(message);
} else {
// Process the message within 10 seconds.
processWithin10s(message);
}
}
private void startWorkManagerJob(RemoteMessage message) {
Log.d(TAG, "Start new job processing.");
}
private void processWithin10s(RemoteMessage message) {
Log.d(TAG, "Processing now.");
}
7. Send downlink messages.
Currently, you can only use REST APIs on the server to send downlink messages through a third-party manufacturer's push messaging channel.
The following is the URL for calling the API using HTTPS POST:
Code:
POST https://push-api.cloud.huawei.com/v1/[appId]/messages:send
The request header looks like the following:
Code:
Content-Type: application/json; charset=UTF-8
Authorization: Bearer CF3Xl2XV6jMKZgqYSZFws9IPlgDvxqOfFSmrlmtkTRupbU2VklvhX9kC9JCnKVSDX2VrDgAPuzvNm3WccUIaDg==
An example of the notification message body is as follows:
Code:
{
"validate_only": false,
"message": {
"android": {
"notification": {
"title": "test title",
"body": "test body",
"click_action": {
"type": 3
}
}
},
"token": ["pushtoken1"]
}
}
And just like that, my app has got the ability to send its push messages to mobile phones of different manufacturers — without any other configurations. Easy-peasy, right?
Conclusion​Today's highly developed mobile Internet has made push messaging an important and effective way for mobile apps to improve user engagement and stickiness. A great obstacle for push messaging to effectively play its role is the highly diversified mobile phone market that is inundated with various manufacturers.
In this article, I demonstrated my solution to aggregate the push channels of different manufacturers, which allowed my app to push messages in a unified way to devices made by those manufacturers. As proven, the whole implementation process is both straightforward and cost-effective, delivering a better messaging effect of push messages by ensuring that they can reach a bigger user base supported by various manufacturers.

Categories

Resources