More information like this, you can visit HUAWEI Developer Forum
Introduction
This article shows the setp to integrate HMS Flutter Location plugin with a news app.
The news app will obtain the country that the user is located in. It will then fetch that country's news headlines and display them onto a list.
For example, if the user is currently located in Hong Kong, the app will show Hong Kong's news headlines on launch. The user may switch to read other countries' news headlines afterwards.
{
"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 datasource of the news headlines are obtained from the NewsAPI.
Configuration
Assuming that there is already a running Flutter app,
*Update: for 1) and 2), the plugin is now uploaded to pub.dev, there is no need to download and configure it manually.
Add this to your pubspec.yaml is the preferred way.
Code:
dependencies:
huawei_location: ^4.0.4+300
1) Download the huawei_location flutter plugin and unzip it. For this project, it is placed under the project's root.
2) Configure pubspec.yaml to add the following under dependencies. Replace the path to your own's.
Code:
huawei_location:
path: 'hms/location/huawei_location'
3) Configure AndroidManifest.xml for location permission.
Code:
<uses-permission android:name="android.permission.ACCESS_COARES_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Project Structure
The architecture of the flutter project is shown below, which is adapted from this repo.
https://github.com/FilledStacks/flutter-tutorials/tree/master/010-provider-architecture
The project is layered into three parts, namely UI, Services and Business Logic.
The UI is dumb and display only what it is given. It will not contain any logic to process the data.
The Service provides various services and exposes APIs for others to use.
The business logic contains view models and models etc.
Since the UI is pretty simple and does not contain any logic to process data, we will mainly focus on Services and Business Logic.
Services
1) Permission Service
Accessing user's location generally requires permission at runtime.
The permission services expose two methods to achieve this. For convenience, the built-in PermissionHandler from Huawei-location plugin is used.
Code:
class PermissionServicesImpl implements PermissionServices {
PermissionHandler _permissionHandler = PermissionHandler();
@override
Future<bool> hasLocationPermission() async {
return _permissionHandler.hasLocationPermission();
}
@override
Future<bool> requestLocationPermission() async {
return _permissionHandler
.requestLocationPermission();
}
}
For this app, the permission to obtain user's location information is acquired during app launch. If the user has allowed, the country code obtained is saved with SharedPreferences.
Code:
Future<void> _initApp() async {
final isPermitted = await _permissionServices.requestLocationPermission();
if(isPermitted == null) {
await _sharedPreferencesServices.saveCountryCode(CommonString.defaultCountry);}
if(isPermitted) {
final hwLocation = await _locationService.getHWLocation();
if(hwLocation != null) {
await _sharedPreferencesServices.saveCountryCode(hwLocation.countryCode);
}
} else {
await _sharedPreferencesServices.saveCountryCode(CommonString.defaultCountry);
}
}
2) Location Service
The location service provides only one method to return HWLocation using huawei_location plugin.
It utilizes location plugin's FusedLocationProviderClient.getLastLocationWithAddress(LocationRequest) to acquire HWLocation.
Remember to set LocationRequest.needAddress to true if you need to obtain the address information also.
Code:
class LocationServicesImpl implements LocationService {
final PermissionServices _permissionServices =
serviceLocator<PermissionServices>();
@override
Future<HWLocation> getHWLocation() async {
if (await _permissionServices.hasLocationPermission()) {
FusedLocationProviderClient locationService =
FusedLocationProviderClient();
LocationRequest locationRequest = LocationRequest();
locationRequest.needAddress = true;
final hwLocation = locationService
.getLastLocationWithAddress(locationRequest);
return hwLocation;
}
}
}
3) SharedPreferences Service
The shared preferences service allows the ability to store and retreive country code. For simplicity, only the abstract class is shown.
Code:
abstract class SharedPreferencesServices {
Future<void> saveCountryCode(String countryCode);
Future<String> getCountryCode();
}
4) TopHeadlines Service
TopHeadlines service allows the ability to fetch a specific countries' news headlines and also to change to another countries' news headlines. For simplicity, only the abstract class is shown.
Code:
abstract class TopHeadlinesService {
Future<List<Article>> getTopHeadlines(String countryCode);
Future<List<Article>> changeHeadlinesLanguage(String countryCode);
}
Business Logic
1) HeadlinesScreenViewModel:
This viewmodel is responsible for managing the state of the headlines screen, processing data and gluing all parts together.
In case of a change in state, the viewmodel will notify its listneres (the UI), so that they could act on the event.
To complete the picture, in the loadData method, the country code is first retreived from SharedPreferences, the country code is then used to call getTopHeadlines(String countryCode) to fetch the headline news of that particular country.
The app will call loadData at the initState lifecycle method of the headlines screen.
Code:
void loadData() async {
_setIsLoading(true);
final _countryCode = await _sharedPreferencesServices
.getCountryCode()
.timeout(Duration(milliseconds: 2000), onTimeout: () => CommonString.defaultCountry);
_headlines = await _topHeadlinesService
.getTopHeadlines(_countryCode)
.timeout(Duration(milliseconds: 2000), onTimeout: () => null);
_setIsLoading(false);
}
The above explains the necessary parts of using HMS Location kit for Flutter.
If you are interested in the details, feel free to visit the github repo.
https://github.com/lkhe/news_app
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
Introduction
Huawei Game service provides a centralized place for you to manage game services and configure metadata for authorizing and authenticating your game. Using Huawei game service, developer can access range of capabilities to help develop your games more efficiently.
Features
1. Developers can promote their game efficiently and quickly.
2. Developers can easily build the foundation of game by implementing features like achievements and events.
3. Developers can perform in-depth operations tailored to their game and their users.
In this article, we will implement event feature provided by Huawei game service in Tic tac toe game.
{
"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"
}
Prerequisites
1. Developer has created an application on App Gallery Connect. Follow Creating an App.
2. Integrating app gallery connect SDK. Please refer to AppGallery Connect Service Getting Started.
3. Developer has integrated Huawei Account kit. Follow this tutorial to integrate account kit.
4. HUAWEI mobile phone with HMS Core 4.0.0.300 or later installed.
Setup:
1. Enable Huawei Game service in Manage APIS. Please refer to Service Enabling.
2. Add appgallery connect plug-in in app-level build.gradle
Code:
apply plugin: 'com.huawei.agconnect'
3. Add following dependencies in app-level build.gradle and click on Sync Now and wait till synchronization is done.
Code:
dependencies {
implementation 'com.huawei.hms:base:4.0.4.301'
implementation 'com.huawei.hms:hwid:4.0.4.300'
implementation 'com.huawei.hms:iap:4.0.4.300'
implementation 'com.huawei.hms:game:4.0.3.301'
}
Initialization
Once Initial set up is done, let’s implement Huawei game service in Tic tac toe game
1. Add the following code in onCreate() method of Application class.
Code:
public class GameServiceApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
HuaweiMobileServicesUtil.setApplication(this);
}
@Override
public void onTerminate() {
super.onTerminate();
}
}
2. To initialize the game
Code:
private void init() {
JosAppsClient appsClient = JosApps.getJosAppsClient(this, null);
appsClient.init();
Log.i(TAG, "initialization success");
}
Signin In
1. When app is launched, Huawei sign-in page is displayed.
2. User enters Huawei Huawei ID and password to sign in.
3. After a successful sign in, the app obtains player information corresponding to Huawei ID.
Please refer to this article for sign in implementation.
Game Events
The Game events allow developer to collect specific data generated by players and store them on Huawei game server for AppGallery connect. In this article, we will collect data pertaining to player win. Every time players win the match, we will store it in Huawei game server.
Creating an Event in AppGallery Connect
1. Sign in to AppGallery Connect and select My apps.
2. Select an app from the app list to create an event.
3. Click the Operate tab and go to Products > Game Event. Click Create.
4. Configure the event information and click Save.
5. Check your event ID on the event list and properly save the ID for event development.
Implementation of Event
1. To initialize EventsClient instance
Code:
EventsClient client = Games.getEventsClient(this, mAuthHuaweiId);
mAuthHuaweiId is obtained during sign in.
2. To submit the event
Code:
client.grow(eventId, growAmount);
eventId indicates the ID of the event which is generated while defining the event in AppGallery connect. In our app we will submit the event everytime players win the match.
The growAmount parameter specifies an increment amount of the event value.
To Obtain Events
Following code can be used to obtain the events.
Code:
Task<List<Event>> task = client.getEventList(forceReload);
forceReload is a Boolean type used to indicate whether to obtain data stored on the Huawei game server or locally cached data.
Following code shows how list of events are returned.
Code:
task.addOnSuccessListener(new OnSuccessListener<List<Event>>() {
@Override
public void onSuccess(List<Event> data) {
if (data == null) {
Log.w("Event", "event is null");
return;
}
for (Event event : data) {
Log.i("Event", "event id:" + event.getEventId());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
if (e instanceof ApiException) {
String result = "errorCode:"
+ ((ApiException) e).getStatusCode();
Log.e("Event", result);
}
}
});
We will show the retrieved events list in recyclerview. Clicking on event list item will show details about the events.
Code:
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Event event = eventList.get(position);
final String eventId = event.getEventId();
Glide.with(context).load(event.getThumbnailUri()).into(holder.eventImage);
holder.eventName.setText(event.getName());
holder.eventAmonut.setText("value:"+event.getValue() + "#" + event.getLocaleValue());
holder.eventDes.setText(event.getDescription());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBtnClickListener.onItemClick(position);
}
});
holder.eventReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBtnClickListener.reportEvent(eventId);
}
});
}
Screenshots
Summary
In this article, we understood initial setup and game event features of Huawei Game Service. In next article, we will discuss more features provided by Huawei Game service.
Source code can be downloaded from https://github.com/DTSE-India-Community/Huawei-Game-Service
How many days it will take to get data reflected in AGC.
More information like this, you can visit HUAWEI Developer Forum
Original link: https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202333898987840045&fid=0101187876626530001
{
"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 Awareness Kit provides our application to obtain information such as current time, location, behavior, audio device status, ambient light, weather, and nearby beacons. Using this information we can get an advantage over user's current situation more efficiently and can manipulate data for better user experience.
In this article, we will use weather information using HMS Awareness Kit for manipulating warm up exercise for user.
Demo
In the above demo, the warm up exercise for user will get change according to the weather condition. Here the weather condition is divided into two parts:
1) Outdoor warm up exercise: When the weather condition is normal such as sunny or not raining, then the warm up exercise will get change to running.
2) Inside warm up exercise: When the weather condition is abnormal such as raining or snow fall, then the warm up exercise will get change to invisible jumping rope, burpee and squats.
By this way we are providing user a better experience without avoiding any exercise due to certain condition. It’s a win-win situation for developers to not to lose any user due to bad user experience.
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) 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 AppGallery connect.
4) Enable awareness kit setting in Manage APIs section.
5) Provide the SHA Key in App Information Section.
6) Provide storage location.
7) 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.
8) Enter the below maven url inside the repositories of buildscript and allprojects (project build.gradle file):
Code:
maven { url ‘http://developer.huawei.com/repo/’ }
9) Enter the below plugin in the app build.gradle file:
Code:
apply plugin: ‘com.huawei.agconnect’
10) Enter the below HMS Push kit dependencies in the dependencies section:
Code:
implementation ‘com.huawei.hms:awareness:1.0.6.301’
11) Enter the below permission in android manifest file
Code:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
12) Now Sync the gradle.
Weather Awareness
It is used for providing weather information such as current day or next seven days weather information of a specific device location. It does not support barrier information or function.
Code:
public void sendWeatherId(){
Awareness.getCaptureClient(this).getWeatherByDevice()
.addOnSuccessListener(new OnSuccessListener<WeatherStatusResponse>() {
@Override
public void onSuccess(WeatherStatusResponse weatherStatusResponse) {
WeatherStatus weatherStatus = weatherStatusResponse.getWeatherStatus();
List<HourlyWeather> hourlyWeather = weatherStatus.getHourlyWeather();
Utility.setWeatherId(getApplicationContext(),hourlyWeather.get(1).getWeatherId());
if(Utility.getWeatherId(getApplicationContext())!=0){
goToValidPage();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.e("TAG", "get Hourly weather failed");
}
});
}
The above code is used to get the weather information such as sunny, rain, cloudy etc. Using this information we will manipulate the warm up exercise and show user the list of exercise.
getWeatherByDevice
This method is used to obtain the weather information using the current location of a device. There are some restriction using this method:
1) The total number of capture API calls every 5 seconds cannot exceed 20
2) The total number of capture API calls every hour cannot exceed 1000
3) This function is available only on device with API level 24 or later
4) ACCESS_FINE_LOCATION permission is needed in android manifest file.
WeatherStatus
This is the main API where we will fetch the weather id. Using this id we will manipulate the exercise. This API contain five methods:
1) getAqi()
2) getWeatherSituation()
3) getDailyWeather()
4) getHourlyWeather()
5) getLiveInfo()
Here we will use getHourlyWeather to obtain weather information in the next 24 hours. The information will fetch weather ID, time, temperature and rainfall probability.
Opening YouTube Video in HMS devices
Code:
public static void watchYoutubeVideo(Context context, String id){
try {
Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com/watch?v=" + id));
context.startActivity(webIntent);
} catch (ActivityNotFoundException ex) {
}
}
The Id here is YouTube Id.
CountDownTime
As the name implies to counts down the time specified in milliseconds.
Code:
mCountDownTimer = new CountDownTimer(TIMER_DURATION, TIMER_INTERVAL) {
@Override
public void onTick(long millisUntilFinished) {
txtTimer.setText("00:"+(millisUntilFinished / 1000 < 10 ? "0"+ millisUntilFinished / 1000 : String.valueOf(millisUntilFinished / 1000)));
mTimeRemaining = millisUntilFinished; // Saving timeRemaining in Activity for pause/resume of CountDownTimer.
}
@Override
public void onFinish() {
mCountDownTimer.cancel();
Intent intent = new Intent(ReadyActivity.this, CurrentWorkoutActivity.class);
startActivity(intent);
finish();
}
}.start();
Timer
In case user go for run we need to have a timer to capture the duration of its completion.
Code:
private void timer (){
Timer timer = new Timer();
countTimer = 0;
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
String s_time = String.format("%02d:%02d:%02d",
countTimer / 3600,
(countTimer % 3600) / 60,
countTimer % 60);
System.out.println("TIMER >>>" + s_time);
txtTimer.setText(s_time);
if (!pauseTimer) countTimer++;
}
});
}
}, 1000, 1000);
}
What we learn?
We learn how to manipulate data using HMS Weather Awareness Kit and also situation where we need the most.
GitHub
Very soon I am going to post the entire code on GitHub. So come back again to check it out.
For more reference
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/service-introduction-0000001050031140-V5
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/weather-awareness-0000001050121038-V5
{
"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"
}
AppGalleryKit App and AppGalleryKit Game services allows to jointly operate the apps with Huawei and share revenue generated in the process. Developer will have access to Huawei’s diverse services including HUAWEI AppGallery connection, data reports, activity operations, and user operations to obtain more premium HUAWEI AppGallery resources in order to promotion purposes.
To enable AppGalleryKit App or AppGalleryKitGame operations, you need to sign the HUAWEI AppGallery Connect Distribution Service Agreement For Paid Apps with Huawei. For details about the joint operations process, please refer to Joint Operations Services at a Glance.
AppGalleryKit App and AppGalleryKit Game is a product concept derived from Account, Analytics, In-App Purchases and other kits. With AppGalleryKit App or AppGalleryKit Game, initializing the app, updating the app, implementing Account Kit is optional. But it is necessary to implementing In-App Purchases kit to use AppGalleryKit App or AppGalleryKit Game. Also it is advised that use Analytics Kit, Auth Service, Crash Service, A/B Testing and APM.
AppGalleryKitApp or AppGalleryKitGame is not pure kit integration. It is required for developers to sign AppGalleryKitApp or AppGalleryKitGame related agreements and they are derived from many features.
Initiliazing app, updating the app, Account Kit and In-App Purchases can be implemented seperately. These kits do not depend on AppGalleryKitApp or AppGalleryKitGame. But AppGalleryKitApp or AppGalleryKitGame depends on these kits.
Although we are not going to use AppGalleryKitApp or AppGalleryKit game, we can still use the update status of the application. In this article, we will check if there is an update in a demo app. Of course due to this app will not be in AppGallery market, there will not any update required.
In order to use this feature, first HMS Core is needed to be integrated to the project.
You can click this link to integrate HMS Core to your project.
Adding Dependency
After HMS Core is integrated, app-service library needs to be implemented.
Code:
implementation 'com.huawei.hms:appservice:{version}' // Currently version is 5.0.4.302
We will create a checkUpdate method and use it in onCreate. JosApps.getAppUpdateClient method, AppUpdateClient instance will be obtained. This object provides the methods related to app update. checkAppUpdate method, checks for app updates after the app is launched and initialized.
Java:
private void checkUpdate(){
AppUpdateClient client = JosApps.getAppUpdateClient(this);
client.checkAppUpdate(this, new UpdateCallBack(this));
}
We need to create a static class which is UpdateCallBack and it will implement CheckUpdateCallBack. CheckUpdateCallBack returns a result for checking for app updates. It requires onUpdateInfo, onMarketInstallInfo, onMarketStoreError and onUpdateStoreError methods are implemented.
in onUpdateInfo method, we can get status code, fail code, fail reason and other informations.
For more information you can click this link.
Code:
private static class UpdateCallBack implements CheckUpdateCallBack {
private final WeakReference<MainActivity> weakMainActivity;
private UpdateCallBack(MainActivity mainActivity) {
this.weakMainActivity = new WeakReference<>(mainActivity);
}
public void onUpdateInfo(Intent intent) {
if (intent != null) {
MainActivity mainActivity = null;
if (weakMainActivity.get() != null){
mainActivity = weakMainActivity.get();
}
int status = intent.getIntExtra(UpdateKey.STATUS, 100);
int rtnCode = intent.getIntExtra(UpdateKey.FAIL_CODE, 200);
String rtnMessage = intent.getStringExtra(UpdateKey.FAIL_REASON);
Serializable info = intent.getSerializableExtra(UpdateKey.INFO);
if (info instanceof ApkUpgradeInfo && mainActivity != null ) {
AppUpdateClient client = JosApps.getAppUpdateClient(mainActivity);
//Force Update option is selected as false.
client.showUpdateDialog(mainActivity, (ApkUpgradeInfo) info, false);
Log.i("AppGalleryKit", "checkUpdatePop success");
}
if(mainActivity != null) {
//status --> 3: constant value NO_UPGRADE_INFO, indicating that no update is available.
Log.i("AppGalleryKit","onUpdateInfo status: " + status + ", rtnCode: "
+ rtnCode + ", rtnMessage: " + rtnMessage);
}
}
}
@Override
public void onMarketInstallInfo(Intent intent) {
//onMarketInstallInfo
}
@Override
public void onMarketStoreError(int i) {
//onMarketStoreError
}
@Override
public void onUpdateStoreError(int i) {
//onUpdateStoreError
}
}
In this example, due to we do not have the application released in the market, we got a status code which is equal to 3. This indicates that for the application there is no upgrade needed.
For all status codes, you can check the below image.
For more details, you can check AppGalleryKit App and AppGalleryKit Game development guide links in reference section. Also you can download this demo application from the Github link.
Reference
AppGalleryKit App
AppGalleryKit Game
Github
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