Introduction
Huawei provides Remote Configuration service to manage parameters online, with this service you can control or change the behavior and appearance of you app online without requiring user’s interaction or update to app. By implementing the SDK you can fetch the online parameter values delivered on the AG-console to change the app behavior and appearance.
{
"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"
}
Functional features
1. Parameter management: This function enables user to add new parameter, delete, update existing parameter and setting conditional values.
2. Condition management: This function enables user to adding, deleting and modifying conditions and copy and modify existing conditions. Currently, you can set the following conditions version, country/region, audience, user attribute, user percentage, time and language. You can expect more conditions in the future.
3. Version management: This feature function supports user to manage and rollback up to 90 days of 300 historical versions for parameters and conditions.
4. Permission management: This feature function allows account holder, app administrator, R&D personnel, and administrator and operations personals to access Remote Configuration by default.
Service use cases
Change app language by Country/Region
Show Different Content to Different Users
Change the App Theme by Time
Development Overview
You need to install Unity software and I assume that you have prior knowledge about the unity and C#.
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.
Unity software installed.
Visual Studio/Code installed.
HMS Core (APK) 4.X or later.
Integration Preparations
1. Create a project in AppGallery Connect.
2. Create Unity project.
3. Huawei HMS AGC Services to project.
4. Download and save the configuration file.
Add the agconnect-services.json file following directory Assests > Plugins > Android
5. Add the following plugin and dependencies in LaucherTemplate.
Code:
apply plugin:'com.huawei.agconnect'
Code:
implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.4.1.300'
implementation 'com.huawei.agconnect:agconnect-core:1.4.2.301'
6. Add the following dependencies in MainTemplate.
Code:
apply plugin: 'com.huawei.agconnect'
Code:
implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.4.1.300'
implementation 'com.huawei.agconnect:agconnect-core:1.4.2.301'
7. Add dependencies in build script repositories and all project repositories & class path in BaseProjectTemplate.
Code:
maven { url 'https://developer.huawei.com/repo/' }
8. Configuring project in AGC
9. Create Empty Game object rename to RemoteConfigManager, UI canvas texts and button and assign onclick events to respective text and button as shown below.
RemoteConfigManager.cs
C#:
using UnityEngine;
using HuaweiService.RemoteConfig;
using HuaweiService;
using Exception = HuaweiService.Exception;
using System;
public class RemoteConfigManager : MonoBehaviour
{
public static bool develporMode;
public delegate void SuccessCallBack<T>(T o);
public delegate void SuccessCallBack(AndroidJavaObject o);
public delegate void FailureCallBack(Exception e);
public void SetDeveloperMode()
{
AGConnectConfig config;
config = AGConnectConfig.getInstance();
develporMode = !develporMode;
config.setDeveloperMode(develporMode);
Debug.Log($"set developer mode to {develporMode}");
}
public void showAllValues()
{
AGConnectConfig config = AGConnectConfig.getInstance();
if(config!=null)
{
Map map = config.getMergedAll();
var keySet = map.keySet();
var keyArray = keySet.toArray();
foreach (var key in keyArray)
{
Debug.Log($"{key}: {map.getOrDefault(key, "default")}");
}
}else
{
Debug.Log(" No data ");
}
config.clearAll();
}
void Start()
{
SetDeveloperMode();
SetXmlValue();
}
public void SetXmlValue()
{
var config = AGConnectConfig.getInstance();
// get res id
int configId = AndroidUtil.GetId(new Context(), "xml", "remote_config");
config.applyDefault(configId);
// get variable
Map map = config.getMergedAll();
var keySet = map.keySet();
var keyArray = keySet.toArray();
config.applyDefault(map);
foreach (var key in keyArray)
{
var value = config.getSource(key);
//Use the key and value ...
Debug.Log($"{key}: {config.getSource(key)}");
}
}
public void GetCloudSettings()
{
AGConnectConfig config = AGConnectConfig.getInstance();
config.fetch().addOnSuccessListener(new HmsSuccessListener<ConfigValues>((ConfigValues configValues) =>
{
config.apply(configValues);
Debug.Log("===== ** Success ** ====");
showAllValues();
config.clearAll();
}))
.addOnFailureListener(new HmsFailureListener((Exception e) =>
{
Debug.Log("activity failure " + e.toString());
}));
}
public class HmsFailureListener:OnFailureListener
{
public FailureCallBack CallBack;
public HmsFailureListener(FailureCallBack c)
{
CallBack = c;
}
public override void onFailure(Exception arg0)
{
if(CallBack !=null)
{
CallBack.Invoke(arg0);
}
}
}
public class HmsSuccessListener<T>:OnSuccessListener
{
public SuccessCallBack<T> CallBack;
public HmsSuccessListener(SuccessCallBack<T> c)
{
CallBack = c;
}
public void onSuccess(T arg0)
{
if(CallBack != null)
{
CallBack.Invoke(arg0);
}
}
public override void onSuccess(AndroidJavaObject arg0)
{
if(CallBack !=null)
{
Type type = typeof(T);
IHmsBase ret = (IHmsBase)Activator.CreateInstance(type);
ret.obj = arg0;
CallBack.Invoke((T)ret);
}
}
}
}
10. Click to Build apk, choose File > Build settings > Build, to Build and Run, choose File > Build settings > Build And Run
Result
Tips and Tricks
Add agconnect-services.json file without fail.
Make sure dependencies added in build files.
Make sure that you released once parameters added/updated.
Conclusion
We have learnt integration of Huawei Remote Configuration Service into Unity Game development. Remote Configuration service lets you to fetch configuration data from local xml file and online i.e. AG-Console,changes will reflect immediately once you releases the changes.Conclusion is service lets you to change your app behaviour and appearance without app update or user interaction.
Thank you so much for reading article, hope this article helps you.
Reference
Unity Manual
GitHub Sample Android
Huawei Remote Configuration service
Read in huawei developer forum
Related
More information about this, you can visit HUAWEI Developer Forum
Introduction
This article will guide you to use A/B testing in android project. It will provide details to use HMS and GMS.
Steps
1. Create App in Android
2. Configure App in AGC
3. Integrate the SDK in our new Android project
4. Integrate the dependencies
5. Sync project
Procedure
Step1: Create application in android studio.
HMS related dependencies, Add below dependencies in app directory
Code:
implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.3.1.300'
apply plugin:'com.huawei.agconnect'
Add below dependencies in root directory
Code:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
GMS related dependencies, Add below dependencies in app directory
Code:
implementation 'com.google.android.gms:play-services-analytics:17.0.0'
implementation 'com.google.firebase:firebase-config:19.2.0'
Add below dependencies into root directory
Code:
classpath 'com.google.gms:google-services:4.3.3'
Step2: Create MobileCheckService class, using this class you can identify whether the device has HMS or GMS.
Code:
class MobileCheckService {
fun isGMSAvailable(context: Context?): Boolean {
if (null != context) {
val result: Int = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)
if (com.google.android.gms.common.ConnectionResult.SUCCESS === result) {
return true
}
}
return false
}
fun isHMSAvailable(context: Context?): Boolean {
if (null != context) {
val result: Int = HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context)
if (com.huawei.hms.api.ConnectionResult.SUCCESS == result) {
return true
}
}
return false
}
}
Step3: Create instance for Mobilecheckservice inside activity class. Inside OnCreate() call checkAvailableMobileService().This method return whether the device has HMS or GMS.
Code:
private fun checkAvailableMobileService() {
if (mCheckService.isHMSAvailable(this)) {
Toast.makeText(baseContext, "HMS Mobile", Toast.LENGTH_LONG).show()
configHmsTest()
} else
if (mCheckService.isGMSAvailable(this)) {
Toast.makeText(baseContext, "GMS Mobile", Toast.LENGTH_LONG).show()
configGmsTest()
} else {
Toast.makeText(baseContext, "NO Service", Toast.LENGTH_LONG).show()
}
}
Step4: If the device support HMS, then use AGConnectConfig.
Code:
private fun configHmsTest() {
val config = AGConnectConfig.getInstance()
config.applyDefault(R.xml.remote_config_defaults)
config.clearAll()
config.fetch().addOnSuccessListener { configValues ->
config.apply(configValues)
config.mergedAll
var sampleTest = config.getValueAsString("Festive_coupon")
Toast.makeText(baseContext, sampleTest, Toast.LENGTH_LONG).show()
}.addOnFailureListener { Toast.makeText(baseContext, "Fetch Fail", Toast.LENGTH_LONG).show() }
}
Step5: If the device support GMS, then use FirebaseRemoteConfig.
Code:
private fun configGmsTest() {
val firebase = FirebaseRemoteConfig.getInstance();
val configSettings = FirebaseRemoteConfigSettings.Builder().build()
firebase.setConfigSettingsAsync(configSettings)
firebase.setDefaultsAsync(R.xml.remote_config_defaults)
firebase.fetch().addOnCompleteListener { configValues ->
if (configValues.isSuccessful) {
firebase.fetchAndActivate()
var name = firebase.getString("Festive_coupon")
Toast.makeText(baseContext, name, Toast.LENGTH_LONG).show()
} else {
Toast.makeText(baseContext, "Failed", Toast.LENGTH_LONG).show()
}
}
}
App Configuration in Firebase:
Note: A/B test is using HMS configuration, refer
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201248355275100167&fid=0101187876626530001
Step1: To configure app into firebase Open firebase https://console.firebase.google.com/u/0/?pli=1
{
"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"
}
Step2: Click Add Project and add required information like App Name, package name, SHA-1.
Step3: After configuration is successful, then click A/B Testing in Grow menu.
To Start A/b testing experiment Click Create experiment button, It will show you list of supported experiments. Using Firebase you can do three experiments.
· Notifications
· Remote Config
· In-App Messaging
Notification: This experiment will use for sending messages to engage the right users at the right moment.
Remote Config: This experiment will use to change app-behavior dynamically and also using server-side configuration parameters.
In-App Messaging: This experiment will use to send different In-App Messages.
Step4: Choose AbTesting > Remote Config > Create a Remote Config experiment, provide the required information to test, as follows
Step5: Choose AbTesting > Remote Config > App_Behaviour, following page will display.
Step6: Click Start experiment, then start A/B test based on the experiment conditions it will trigger
Step7: After successful completion of experiment, we can get report.
Conclusion:
Using A/B test, you can control the entire experiment from HMS or GMS dashboard, this form of testing will be highly effective for the developers.
Reference:
To know more about firebase console, follow the URL https://firebase.google.com/docs/ab-testing
Share your thoughts on this article, if you are already worked with A/B tests, then you can share your experience on separation between them with us
More information like this, you can visit HUAWEI Developer Forum
Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201346103655580149&fid=0101188387844930001
Introduction
This article is based on Huawei Mobile Services application. I have developed Trip Booking Android app. We can provide the solution for HMS based multiple kits such as Account Kit, Huawei Ads, Huawei Map, and Huawei Analysts to use in Trip Booking. So users can book any trip.
In this application, users can plan trips and advance books. It will provide the ongoing trip cities wise with weather forecasting so that users can easily plan a trip and book trip and also can find popular cities with budget hotels and much more.
Service Process
{
"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"
}
The process is described as follows:
1. A user signs in to your app using a HUAWEI ID.
2. Your app sends a sign-in request to the Account SDK.
3. The Account SDK brings up the user sign-in authorization interface, explicitly notifying the user of the content to be authorized based on the authorization scope contained in the sign-in request.
4. After the user authorizes your app to access the requested content, the Account SDK returns the authorization code to your app.
5. Based on the authorization code, your app obtains the access token, refresh token, and ID token from the HUAWEI Account Kit server.
6. Based on the access token, your app server obtains openId of the user from the HUAWEI Account Kit server.
7. If the access token or ID token has expired, your app server obtains a new access token or ID token using the refresh token.
Prerequisite
1. A computer (desktop or laptop).
2. A Huawei phone used for running the app with HMS Core (APK) 3.0.0.300 or later.
3. A data cable used for connecting the computer to the Huawei phone.
4. Android Studio 3.0 or later.
5. Java SDK 1.7 or later.
6. HMS Core SDK 4.0.0.300 or later.
7. Must have Huawei Developer Account.
Things Need To Be Done
1. Create an app in AppGallery Connect and enable the service.
2. Create an Android Studio project.
3. Start development with kit integration inside the application.
4. Launch the application.
Create a project on AppGalleryConnect portal
1. Navigate to AppGalleryConnect, create a new project.
2. Enter all details regarding your application, enable Account Kit API, after that download the configuration JSON file, and then add into your android studio project.
Create a project in Android Studio:
Navigate to android studio and create a new android project, provide all details of your project, and then add AGC and Account kit SDK dependencies.
1. Add maven URL and add following AppGalleryConnect classpath.
Code:
buildscript {
repositories {
maven {url 'http://developer.huawei.com/repo/'}
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
classpath 'com.huawei.agconnect:agcp:1.0.0.300'
}
}
allprojects {
repositories {
maven {url 'http://developer.huawei.com/repo/'}
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
2. Add the following dependencies in app module based Gradle file, then sync your project.
Code:
implementation "com.google.code.gson:gson:2.8.5"
implementation('com.huawei.hms:hwid:4.0.4.300')
implementation "com.squareup.okhttp3:okhttp:3.14.2"
implementation 'com.squareup.okio:okio:1.14.1'
Start development with kit integration inside the application
I have created the following package inside the project.
LoginActivity
In this screen, I have integrated login functionality with Huawei Id.
Which cover the following APIs
1. Call the HuaweiIdAuthParamsHelper.setAuthorizationCode API to send an authorization request.
Code:
HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setAuthorizationCode().createParams();
2. Call the getService API of HuaweiIdAuthManager to initialize the HuaweiIdAuthService object.
Code:
HuaweiIdAuthService service = HuaweiIdAuthManager.getService(MainActivity.this, authParams);
3. Call the HuaweiIdAuthService.getSignInIntent method to bring up the HUAWEI ID sign-in authorization interface.
Code:
startActivityForResult(mAuthManager.getSignInIntent(), Constant.REQUEST_SIGN_IN_LOGIN);
4. Process the sign-in result after the authorization is complete.
Code:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Constant.REQUEST_SIGN_IN_LOGIN) {
Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult();
Log.i(TAG, huaweiAccount.getDisplayName() + " signIn success ");
Log.i(TAG, "AccessToken: " + huaweiAccount.getAccessToken());
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("user", huaweiAccount.getDisplayName());
startActivity(intent);
this.finish();
} else {
Log.i(TAG, "signIn failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
if (requestCode == Constant.REQUEST_SIGN_IN_LOGIN_CODE) {
//login success
Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult();
Log.i(TAG, "signIn get code success.");
Log.i(TAG, "ServerAuthCode: " + huaweiAccount.getAuthorizationCode());
} else {
Log.i(TAG, "signIn get code failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
}
MainActivity
In this screen, I have integrated all fragments which are related to application and also added Logout functionality.
Code:
public class MainActivity extends AppCompatActivity {
private static String TAG = MainActivity.class.getName();
private AppBarConfiguration mAppBarConfiguration;
private HuaweiIdAuthService mAuthManager;
private HuaweiIdAuthParams mAuthParam;
private void setUser(String name) {
NavigationView navigationView = findViewById(R.id.nav_view);
View headerView = navigationView.getHeaderView(0);
TextView navUsername = headerView.findViewById(R.id.txt_user_name);
navUsername.setText(name);
}
private void logOut() {
mAuthParam = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.createParams();
mAuthManager = HuaweiIdAuthManager.getService(this, mAuthParam);
Task<Void> signOutTask = mAuthManager.signOut();
signOutTask.addOnSuccessListener(aVoid -> {
Log.i(TAG, "signOut Success");
Intent intent = new Intent(this, LoginScreen.class);
startActivity(intent);
this.finish();
})
.addOnFailureListener(e -> Log.i(TAG, "signOut fail"));
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_logout:
logOut();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Launch the application
Let us launch our application, see the result
If you have any doubts or queries. Leave your valuable comment in the comment section and do not forget to like and follow me.
References
https://developer.huawei.com/consumer/en/hms/huawei-accountkit
is it possible to sign in using phone number?
Very useful, thanks.
Overview
QUIC (Quick UDP Internet Connections) is a general-purpose transport layer network protocol.
QUIC is a new transport which reduces latency compared to that of TCP. On the surface, QUIC is very similar to TCP+TLS+HTTP/2 implemented on UDP. Because TCP is implemented in operating system kernels, and middlebox firmware, making significant changes to TCP is next to impossible.
QUIC reduces round trips by working with UDP. With great features like eliminating head of line blocking, loss recovery over UDP by using multiplexed connections and congestion control, the protocol has evolved and is being widely used.
Introduction of hQUIC
hQUIC provides the ability to fulfil our needs for lower packet loss in our applications, high performance in our network operations and reliable fast connection. It supports the gQUIC protocol and provides intelligent congestion control algorithms to avoid congestions in different network environments.
Advantages
Ease of use: Streamlines APIs and shields low-level network details.
High compatibility: Supports gQUIC and Cronet.
Better experience: Outperforms other protocols in poor network conditions
{
"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"
}
What is Cronet?
Cronet is the networking stack of Chromium put into a library for use on mobile. This is the same networking stack that is used in the Chrome browser by over a billion people. It offers an easy-to-use, high performance, standards-compliant, and secure way to perform HTTP requests.
Cronet is a very well implemented and tested network stack that provides almost everything that a standard app needs from a network layer library, things like DNS, Cookies, SSL/TLS, HTTP(S), HTTP2, Proxy/PAC, OSCP, Web sockets, and F̶T̶P̶(soon to be removed). It also supports HTTP over QUIC, soon to be called HTTP3. This makes it a very attractive library to use as the network layer for your mobile app.
How TCP Works?
TCP allows for transmission of information in both directions. This means that computer systems that communicate over TCP can send and receive data at the same time, similar to a telephone conversation. The protocol uses segments (packets) as the basic units of data transmission.
The actual process for establishing a connection with the TCP protocol is as follows:
1. First, the requesting sender sends the server a SYN packet or segment (SYN stands for synchronize) with a unique, random number. This number ensures full transmission in the correct order (without duplicates).
2. If the receiver has received the segment, it agrees to the connection by returning a SYN-ACK packet (ACK stands for acknowledgement) including the client's sequence number plus 1. It also transmits its own sequence number to the client.
3. Finally, the sender acknowledges the receipt of the SYN-ACK segment by sending its own ACK packet, which in this case contains the receiver's sequence number plus 1. At the same time, the client can already begin transferring data to the receiver.
Prerequisite
1. A computer with Android Studio installed and able to access the Internet
2. A Huawei phone with HMS Core (APK) 5.0.0 or later installed for debugging the app
3. Java JDK (1.7 or later)
4. Android API (level 19 or higher)
5. EMUI 3.0 or later
6. HMS Core (APK) 5.0.0 or later
Integration process
1. Open the build.gradle file in the root directory of your Android Studio project.
Code:
buildscript {
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
google()
...
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
}
}
}
2. Open the build.gradle file in the app directory and add dependency on the SDK.
Code:
dependencies {
implementation 'com.huawei.hms:hquic-provider:5.0.0.300'
}
3. Initialise the service
Code:
HQUICManager.asyncInit(context, new HQUICManager.HQUICInitCallback() {
@Override
public void onSuccess() {
Log.i(TAG, "HQUICManager asyncInit success");
}
@Override
public void onFail(Exception e) {
Log.w(TAG, "HQUICManager asyncInit fail");
}
});
4. Initialise the Cronet Engine
Code:
CronetEngine.Builder builder = new CronetEngine.Builder(context);
builder.enableQuic(true);
builder.addQuicHint(getHost(url), DEFAULT_PORT, DEFAULT_ALTERNATEPORT);
cronetEngine = builder.build();
App Development
I will use APIs of the hQUIC SDK by developing a Speed Test app step by step.
I have created HQUICSericeProvider class in which I will create the service using hQuic APIs.
Let us implements the asynchronous initialization API.
Code:
public class HQUICServiceProvider {
private static final String TAG = "HQUICServiceProvider";
private static final int DEFAULT_PORT = 443;
private static final int DEFAULT_ALTERNATEPORT = 443;
private static Executor executor = Executors.newSingleThreadExecutor();
private static CronetEngine cronetEngine;
private Context context;
private UrlRequest.Callback callback;
public HQUICServiceProvider(Context context) {
this.context = context;
init();
}
public void init() {
HQUICManager.asyncInit(
context,
new HQUICManager.HQUICInitCallback() {
@Override
public void onSuccess() {
Log.i(TAG, "HQUICManager asyncInit success");
}
@Override
public void onFail(Exception e) {
Log.w(TAG, "HQUICManager asyncInit fail");
}
});
}
private CronetEngine createCronetEngine(String url) {
if (cronetEngine != null) {
return cronetEngine;
}
CronetEngine.Builder builder = new CronetEngine.Builder(context);
builder.enableQuic(true);
builder.addQuicHint(getHost(url), DEFAULT_PORT, DEFAULT_ALTERNATEPORT);
cronetEngine = builder.build();
return cronetEngine;
}
private UrlRequest buildRequest(String url, String method) {
CronetEngine cronetEngine = createCronetEngine(url);
UrlRequest.Builder requestBuilder =
cronetEngine.newUrlRequestBuilder(url, callback, executor).setHttpMethod(method);
UrlRequest request = requestBuilder.build();
return request;
}
public void sendRequest(String url, String method) {
Log.i(TAG, "callURL: url is " + url + "and method is " + method);
UrlRequest urlRequest = buildRequest(url, method);
if (null != urlRequest) {
urlRequest.start();
}
}
private String getHost(String url) {
String host = null;
try {
java.net.URL url1 = new java.net.URL(url);
host = url1.getHost();
} catch (MalformedURLException e) {
Log.e(TAG, "getHost: ", e);
}
return host;
}
public void setCallback(UrlRequest.Callback mCallback) {
callback = mCallback;
}
}
More details, you can visit https://forums.developer.huawei.com/forumPortal/en/topic/0203400466275620106
It will support only network call related information?
Xamarin (Microsoft) is a multi-system development platform for mobile services that many developers use. Many AppGallery Connect services now support Xamarin, including Remote Configuration.
Remote Config allows you to make changes to your app remotely by making use of variables that you can define in the AppGallery Console. Different values can be set for different audiences, locations or sections of users. This is a great way to personalise your application, carry out testing of new features or just make updates without having to deploy a new app version.
Install the Xamarin environment and project setup.You’ll need to first download and install Visual Studio 2019.
Open Visual Studio and select Mobile development with .NET to install the Xamarin environment.
{
"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"
}
Next make sure you have enabled the Auth Service in AppGallery Connect.
Open Visual Studio, click Create a new project in the start window, select Mobile App (Xamarin.Forms), and set the app name and other required information.
Right-click your project and choose Manage NuGet Packages.
Search for the Huawei.Agconnect.RemoteConfiguration package on the displayed page and install it.
Download the JSON service file from your AppGallery project and add it into the *Assets directory in your project.
Create a new class named HmsLazyInputStreams.cs, and implement the following code to read the JSON file.
Code:
using System;
using System.IO;
using Android.Content;
using Android.Util;
using Huawei.Agconnect.Config;
namespace AppLinking1
{
public class HmsLazyInputStream : LazyInputStream
{
public HmsLazyInputStream(Context context)
: base(context)
{
}
public override Stream Get(Context context)
{
try
{
return context.Assets.Open("agconnect-services.json");
}
catch (Exception e)
{
Log.Error("Hms", $"Failed to get input stream" + e.Message);
return null;
}
}
}
}
Create a ContentProvider class and add the following code for your file to be read once your app is launched. Ensure that the package name set in ContentProvider, and the one in your project and the one set in AppGallery Connect are the same as the app package name.
Code:
using System;
using Android.Content;
using Android.Database;
using Huawei.Agconnect.Config;
namespace XamarinHmsRemoteConfig
{
[ContentProvider(new string[] { "com.huawei.cordova.remoteconfig.XamarinCustomProvider" }, InitOrder = 99)]
public class XamarinCustomProvider : ContentProvider
{
public override int Delete(Android.Net.Uri uri, string selection, string[] selectionArgs)
{
throw new NotImplementedException();
}
public override string GetType(Android.Net.Uri uri)
{
throw new NotImplementedException();
}
public override Android.Net.Uri Insert(Android.Net.Uri uri, ContentValues values)
{
throw new NotImplementedException();
}
public override bool OnCreate()
{
AGConnectServicesConfig config = AGConnectServicesConfig.FromContext(Context);
config.OverlayWith(new HmsLazyInputStream(Context));
return false;
}
public override ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder)
{
throw new NotImplementedException();
}
public override int Update(Android.Net.Uri uri, ContentValues values, string selection, string[] selectionArgs)
{
throw new NotImplementedException();
}
}
}
Right-click your project and choose Properties. Click Android Manifest on the displayed page and set a package name
Set in app default parameter valuesYou can configure a default parameter value in either of the following ways:
Using an XML resource file. Add a default parameter value XML file to the res/xml directory of your project. Call the ApplyDefault method to read the file.
Or you can use a Map object. Set a default parameter value dynamically through coding.
Code:
IDictionary<string, Java.Lang.Object> ConfigVariables = new Dictionary<string, Java.Lang.Object>();
ConfigVariables.Add("value1", "Default");
AGConnectConfig.Instance.ApplyDefault(ConfigVariables);
Fetch the updated parameter valueCall the fetch API to fetch the updated parameter value from Remote Configuration. The default update interval used by the fetch API is 12 hours and can be set as required.
Code:
AGConnectConfig.Instance.Fetch(fetchInterval).AddOnSuccessListener(new TaskListener(this)).AddOnFailureListener(new TaskListener(this));
Obtain all parameter valuesFor Xamarin.Android apps, the MergedAll API is called to obtain all parameter values including the in-app default parameter value and the on-cloud parameter value. For Android apps, the getMergedAll API is used
And that’s all for integrating Remote Configuration into Xamarin.Android apps. As more and more AppGallery Connect services support Xamarin, I will keep you posted about further integration tutorials.
Huawei AppGallery Connect’s App Messaging service allows you to send targeted, useful in app messages to your users.
The look and content of messages are completely customisable, and there is a wide range of triggers and filters that can be used to decide who will receive a message and when.
Lets take a look today at how we can set this up to work within an Android project.
As always we will start with a fresh project but of course you can just as easily use this guide to build the service into an app you already have!
Enabling the ServiceSign in to AppGallery Connect, click My projects, click your project, go to Grow > App Messaging, and click Use now. For more information, please refer to App Messaging.
If you do not have an Android project, create one first.
After completing these steps, you can start creating an in-app message.
Click New in the upper right corner.
{
"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"
}
Set Name and Description
Set the style and content and click Next.
Select a message type from the Layout drop-down list, and set its style and content. Currently, the Modal, Image, and Banner message types are supported.
Set target users and click Next.
In App, select the name of the app package for which you need to publish the in-app message.
You can click New condition to add a condition for matching target users, which include app version, OS version, language, country/region, audience, and more. Among the types, User attributes are defined under HUAWEI Analytics > Management > User attributes, and Prediction is defined by creating prediction tasks under My projects > Grow > Prediction.
Set the message sending time
Message display is triggered by specific events. App Messaging supports two types of trigger events: preset events and HUAWEI Analytics events.
(Optional) Set conversion events. Before setting a conversion event, you need to toggle it on first, which can be done as follows:
Go to HUAWEI Analytics > Management > Events and toggle Mark as conversion event and Event switch on for the specified event. In addition to the events the SDK collects, you can also create a preset or custom event for event tracking and analysis.
Finally, Click Save or Publish.
Integrating the Service SDKAdd Maven repository configuration to the build.gradle file of your project.
Code:
buildscript {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Open the app-level build.gradle file and configure the App Messaging SDK
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
android {…..}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.huawei.agconnect:agconnect-appmessaging:1.5.2.300'
}
In AppGallery Connect, click My projects, and find your project from the list. Go to Project settings > General information, download the agconnect-services.json file, and save the file to the app directory of your Android project.
Displaying an In-App MessageIf you choose to display a message using the default message layout, the development process is totally coding-free.
By integrating the SDK as above you are all good to go, your creating message will be displayed as per its filters and triggers.
You can also call APIs provided by the service SDK to customize your in-app message.
Customising the Message LayoutFirst, you need to customize a message display class. To do so, implement AGConnectAppMessagingDisplay and override the displayMessage method.
Code:
public class CustomDisplayView implements AGConnectAppMessagingDisplay {
@Override
public void displayMessage(@NonNull AppMessage appMessage,
@NonNull AGConnectAppMessagingCallback callback) {
}
}
Define an AlertDialog in displayMessage and copy the layout file to the code. The sample code is as follows:
Code:
@Override
public void displayMessage(@NonNull AppMessage appMessage, @NonNull AGConnectAppMessagingCallback callback) {
Log.d(TAG, appMessage.getId() + "");
showDialog(appMessage, callback);
}
private void showDialog(@NonNull final AppMessage appMessage, @NonNull final AGConnectAppMessagingCallback callback) {
View view = LayoutInflater.from(activity).inflate(R.layout.custom_view, null, false);
final AlertDialog dialog = new AlertDialog.Builder(activity).setView(view).create();
Button click = view.findViewById(R.id.click);
Button dismiss = view.findViewById(R.id.dismiss);
TextView id = view.findViewById(R.id.id);
id.setText("MessageID: " + appMessage.getId());
click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// set button callback
callback.onMessageClick(appMessage);
callback.onMessageDismiss(appMessage, AGConnectAppMessagingCallback.DismissType.CLICK);
dialog.dismiss();
}
});
dismiss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//set button callback
callback.onMessageDismiss(appMessage, AGConnectAppMessagingCallback.DismissType.CLICK);
dialog.dismiss();
}
});
dialog.show();
dialog.getWindow().setLayout((getScreenWidth(activity) / 4 * 3), LinearLayout.LayoutParams.WRAP_CONTENT);
callback.onMessageDisplay(appMessage);
}
Call addCustomView to implement the custom layout.
Code:
CustomView customView = new CustomView(MainActivity.this);
appMessaging.addCustomView(customView);
Test in app messageObtain the Anonymous Application Identifier (AAID) of your test device, which is used to identify app instances running on mobile devices during app installation. Compared with device-level hardware IDs that cannot be reset, the privacy of AAID is much higher. We can obtain the AAID through coding.
Code:
HmsInstanceId inst = HmsInstanceId.getInstance(this);
Task<AAIDResult> idResult = inst.getAAID();
idResult.addOnSuccessListener(new OnSuccessListener<AAIDResult>() {
@Override
public void onSuccess(AAIDResult aaidResult) {
String aaid = aaidResult.getId();
textView.setText(aaid);
Log.d(TAG, "getAAID success:" + aaid );
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.d(TAG, "getAAID failure:" + e);
}
});
Sign in to AppGallery Connect, go to Grow > App Messaging > Messages, find the message that you need to test, and click Test in the Operation column.
Click Add test user and enter the AAID in the test box.
Click Save. Check whether the test message can be properly displayed and operated.
For details, please refer to the development guide of App Messaging.