What is HUAWEI Game?

HUAWEI Game is a service provided by Huawei that allows for efficient game app development. With HUAWEI Game you can enable users to sign in to your games with just their HUAWEI IDs, for optimally convenient game promotion that leverages Huawei's enormous user base.
In addition, HUAWEI Game supports achievements, which serve as a great way to increase player engagement within your game, and provide players with greater incentives to continue playing the game. Through HUAWEI Game, you can display and manage achievements easily and efficiently.

What You Will Create

In this codelab, you will create an Android app that implements simple game interactions. The app will:

What You Will Learn

What You Will Need

Development Environment and Skill Requirements

Device Requirements

Creating an App and Obtaining the Configuration File

Create an app in AppGallery Connect and obtain the project configuration file agconnect-services.json. The procedure is as follows:

For details, see the HUAWEI HMS Core Integration Preparation.

Enabling HUAWEI Game Service

  1. In AppGallery Connect, go to Develop > Overview > Manage APIs.
  2. Toggle the In-App Purchases, Huawei Account and Game Service switches.

Integrating HMS SDK

For Android Studio, Huawei provides an HMS SDK that can be integrated by using the Maven repository. Before developing your game app, you will need to integrate HMS SDK into your Android Studio project.

  1. In AppGallery Connect, go to Develop > Overview.
  2. In the App information section, click agconnect-services.json to download the configuration file.
  3. Copy the agconnect-service.json file to the project root directory.
  4. Open the Android Studio Project-level build.gradle file.
  5. In the build.gradle file of your Android Studio project, add the following configurations.
    allprojects { repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } } buildscript { repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } } buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.4.0' classpath 'com.huawei.agconnect:agcp:1.2.0.300' } }
  6. Open the Android Studio app-level build.gradle file.
  7. In the build.gradle file in the app directory of your Android Studio project, add the following configurations, and replace {version} with the current HMS SDK version number, which is 4.0.0.300.
    apply plugin: 'com.huawei.agconnect' dependencies { implementation 'com.huawei.hms:hwid:{version}' implementation 'com.huawei.hms:iap:{version}' implementation 'com.huawei.hms:game:{version}' }
  8. Click Sync Now to synchronize the configurations.

Configuring Obfuscation Scripts

  1. Open proguard-rules.pro, the obfuscation configuration file of your Android Studio project.
  2. Add obfuscation configurations.
    -ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;} -keep class com.huawei.gamebox.plugin.gameservice.**{*;}

Scenarios that involve interaction between your game app and HUAWEI Game service include: game sign-in and game achievements. In this codelab, you can create the UI in your Android Studio project, by referring to the following UI layout.

Step 1 Import game related classes.

import com.huawei.hmf.tasks.OnFailureListener; import com.huawei.hmf.tasks.OnSuccessListener; import com.huawei.hmf.tasks.Task; import com.huawei.hms.R; import com.huawei.hms.api.HuaweiApiClient; import com.huawei.hms.common.ApiException; import com.huawei.hms.game.achievement.AchievementListActivity; import com.huawei.hms.jos.AppUpdateClient; import com.huawei.hms.jos.JosApps; import com.huawei.hms.jos.JosAppsClient; import com.huawei.hms.jos.games.AchievementsClient; import com.huawei.hms.jos.games.Games; import com.huawei.hms.jos.games.PlayersClient; import com.huawei.hms.jos.games.player.Player; import com.huawei.hms.jos.games.player.PlayerExtraInfo; import com.huawei.hms.support.api.client.PendingResult; import com.huawei.hms.support.api.client.ResultCallback; import com.huawei.hms.support.api.client.Status; import com.huawei.hms.support.api.entity.core.CommonCode; import com.huawei.hms.support.api.game.CertificateIntentResult; import com.huawei.hms.support.api.game.HuaweiGame; import com.huawei.hms.support.api.game.PlayerCertificationInfo; import com.huawei.hms.support.api.game.ShowFloatWindowResult; import com.huawei.hms.support.hwid.HuaweiIdAuthManager; import com.huawei.hms.support.hwid.result.AuthHuaweiId; import com.huawei.hms.support.hwid.result.HuaweiIdAuthResult;

Step 2 Add a callback listener for the registered Activity in the onCreate method of the Application.

public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); HuaweiMobileServicesUtil.setApplication(this); } @Override public void onTerminate() { super.onTerminate(); } }

Step 3 Initialize the game during game launch.

@OnClick(R.id.btn_init) public void init() { JosAppsClient appsClient = JosApps.getJosAppsClient(this, null); appsClient.init(); showLog("init success"); }

Step 4 Sign in to the game explicitly.

private void signIn() { HuaweiIdSignInClient signInClient = HuaweiIdSignIn.getClient(this, HuaweiIdSignInOptions.DEFAULT_GAMES_SIGN_IN); startActivityForResult(signInClient.getSignInIntent(), 8888); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 8888) { Task<SignInHuaweiId> signInHuaweiIdTask = HuaweiIdSignIn.getSignedInAccountFromIntent(data); if (signInHuaweiIdTask.isSuccessful()) { setHuaweiIdInfo(signInHuaweiIdTask.getResult()); //TODO: Successful sign-in. User information was obtained. Log.i(TAG, "sign-in succeeded, user info: " + signInHuaweiIdTask.getResult().toString()); } else { //Sign-in failed. Log.e(TAG, "sign-in failed, status: " + ((ApiException) signInHuaweiIdTask.getException()).getStatusCode()); } } }@OnClick(R.id.btn_sign_in) public void signIn() { HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM_GAME).createParams(); Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.getService(this, authParams).silentSignIn(); authHuaweiIdTask.addOnSuccessListener(new OnSuccessListener<AuthHuaweiId>() { @Override public void onSuccess(AuthHuaweiId authHuaweiId) { showLog("signIn success"); showLog("display:" + authHuaweiId.getDisplayName()); SignInCenter.get().updateAuthHuaweiId(authHuaweiId); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { ApiException apiException = (ApiException) e; showLog("signIn failed:" + apiException.getStatusCode()); showLog("start getSignInIntent"); signInNewWay(); } } }); } public HuaweiIdAuthParams getHuaweiIdParams() { return new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM_GAME).createParams(); } public void signInNewWay() { Intent intent = HuaweiIdAuthManager.getService(MainActivity.this, getHuaweiIdParams()).getSignInIntent(); startActivityForResult(intent, SIGN_IN_INTENT); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (SIGN_IN_INTENT == requestCode) { handleSignInResult(data); } else { showLog("unknown requestCode in onActivityResult"); } } private void handleSignInResult(Intent data) { if (null == data) { showLog("signIn inetnt is null"); return; } String jsonSignInResult = data.getStringExtra("HUAWEIID_SIGNIN_RESULT"); if (TextUtils.isEmpty(jsonSignInResult)) { showLog("signIn result is empty"); return; } try { HuaweiIdAuthResult signInResult = new HuaweiIdAuthResult().fromJson(jsonSignInResult); if (0 == signInResult.getStatus().getStatusCode()) { showLog("signIn success."); showLog("signIn result: " + signInResult.toJson()); SignInCenter.get().updateAuthHuaweiId(signInResult.getHuaweiId()); } else { showLog("signIn failed: " + signInResult.getStatus().getStatusCode()); } } catch (JSONException var7) { showLog("Failed to convert json from signInResult."); } }

Step 5 Obtain player information.

@OnClick(R.id.btn_get_player) public void getCurrentPlayer() { PlayersClientImpl client = (PlayersClientImpl) Games.getPlayersClient(this, getAuthHuaweiId()); Task<Player> task = client.getCurrentPlayer(); task.addOnSuccessListener(new OnSuccessListener<Player>() { @Override public void onSuccess(Player player) { currentPlayer = player; String result = "display:" + player.getDisplayName() + "\n" + "playerId:" + player.getPlayerId() + "\n" + "playerLevel:" + player.getLevel() + "\n" + "timestamp:" + player.getSignTs() + "\n" + "playerSign:" + player.getPlayerSign(); showLog(result); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog(result); } } }); } protected AuthHuaweiId getAuthHuaweiId() { return SignInCenter.get().getAuthHuaweiId(); }}

Creating an Achievement

  1. Sign in to AppGallery Connect and click My apps.
  2. Find your app from the list and click the corresponding link to open the app development page.
  3. Click the Operate tab, choose Product Operation > Achievement management from the navigation bar to the left, and click Create.
  4. Configure achievement information. After you have completed the configuration, click Save.
    Language: Select a language as needed.
    Name: Enter the achievement name.
    Description: Provide a brief description for the achievement.
    Icon: Upload a 512px x 512px picture in PNG or JPG format.
    Step-based achievement: Select Preset steps must be completed before the achievement is unlocked, and then specify the number of steps in Preset steps.
    Initial state: Select Displayed or Hidden.
    Sequence number: Define the order in which the current achievement appears among all of the achievements.
  5. Obtain the achievement ID in the ID column of the achievement list.

Development Procedures

Step 1 Display Application assistant's achievements page.

@OnClick(R.id.btn_get_achieve_intent) public void getAchievementIntent() { AchievementsClient client = Games.getAchievementsClient(this, getAuthHuaweiId()); Task<Intent> task = client.getShowAchievementListIntent(); task.addOnSuccessListener(new OnSuccessListener<Intent>() { @Override public void onSuccess(Intent intent) { if (intent == null) { showLog("intent = null"); } else { try { startActivityForResult(intent, 1); } catch (Exception e) { showLog("Achievement Activity is Invalid"); } } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog(result); } } }); }

Step 2 Load all achievement data of the current player.
Go to the custom achievement display page AchievementListActivity.

@OnClick(R.id.btn_load_achievement) public void loadAchievement() { loadAchievement(true); } private void loadAchievement(boolean forceReload) { if (getAuthHuaweiId() == null) { showLog("signIn first"); return; } String jString = ""; try { jString = getAuthHuaweiId().toJson(); } catch (JSONException e) { showLog("signIn first"); } Intent intent = new Intent(this, AchievementListActivity.class); intent.putExtra("forceReload", forceReload); intent.putExtra("mSign", jString); startActivity(intent); }

The code for loading all achievement data in AchievementListActivity as follow:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_achievement_list); mContext = this; ButterKnife.bind(mContext); initViews(); initData(); requestData(); } private void initViews() { LinearLayoutManager layoutManager = new LinearLayoutManager(mContext); recyclerView.setLayoutManager(layoutManager); adapter = new AchievementListAdapter(mContext, achievements, mContext); recyclerView.setAdapter(adapter); } private void requestData() { Task<List<Achievement>> task = client.getAchievementList(forceReload); task.addOnSuccessListener(new OnSuccessListener<List<Achievement>>() { @Override public void onSuccess(List<Achievement> data) { if (data == null) { showLog("achievementBuffer is null"); return; } Iterator<Achievement> iterator = data.iterator(); achievements.clear(); while (iterator.hasNext()) { Achievement achievement = iterator.next(); achievements.add(achievement); } adapter.setData(achievements); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog(result); } } }); } private void initData() { Intent intent = getIntent(); forceReload = intent.getBooleanExtra("forceReload", false); String mSignString =intent.getStringExtra("mSign"); try { authHuaweiId =AuthHuaweiId.fromJson(mSignString); } catch (JSONException e) { } client = Games.getAchievementsClient(this, authHuaweiId); }

Click on the achievement to display the details of the achievement.

@Override public void onItemClick(int postion) { Intent intent = new Intent(this, AchievementDetailActivity.class); Achievement achievement = achievements.get(postion); intent.putExtra("achievementName",achievement.getDisplayName()); intent.putExtra("achievementDes",achievement.getDescInfo()); intent.putExtra("unlockedImageUri",achievement.getReachedThumbnailUri()); intent.putExtra("rvealedImageUri",achievement.getVisualizedThumbnailUri()); startActivity(intent); }

Step 3 Reveal a hidden achievement.

@Override public void reveal(String achievementId, boolean isChecked) { if (!isChecked){ client.visualize(achievementId); }else { performRevealImmediate(client,achievementId); } } private void performRevealImmediate(AchievementsClient client, String achievementId) { Task<Void> task = client.visualizeWithResult(achievementId); task.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void v) { showLog("revealAchievemen isSucess"); requestData(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog("achievement is not hidden"+result); } } }); }

Step 4 Increase steps that have been completed for the current achievement.

@Override public void increment(String achievementId, boolean isChecked) { if (!isChecked){ client.grow(achievementId,1); }else { performIncrementImmediate(client,achievementId,1); } } private void performIncrementImmediate(AchievementsClient client, String achievementId, int stepsNum) { Task<Boolean> task = client.growWithResult(achievementId, stepsNum); task.addOnSuccessListener(new OnSuccessListener<Boolean>() { @Override public void onSuccess(Boolean isSucess) { if (isSucess) { showLog("incrementAchievement isSucess"); requestData(); }else { showLog("achievement can not grow"); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog("has bean already unlocked"+result); } } }); }

Step 5 Set the number of steps that have been completed for the current achievement.

private void setAchievementStep(boolean immediate, String achievementId, int stepNum) { AchievementsClient achievementsClient = Games.getAchievementsClient(this, getHuaweiIdInfo()); if (immediate) { Task<Boolean> task = achievementsClient.setStepsImmediate(achievementId, stepNum); task.addOnSuccessListener(new OnSuccessListener<Boolean>() { @Override public void onSuccess(Boolean isSucess) { if (isSucess) Log.i(TAG, "setAchievementSteps isSucess"); else Log.i(TAG, "achievement can not setSteps"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "set failed, status: " + ((ApiException) e).getStatusCode()); } }); } else { achievementsClient.setSteps(achievementId, stepNum); Log.i(TAG, "Asynchronously set achievement step"); } }@Override public void setStep(String achievementId, boolean isChecked) { if (!isChecked){ client.makeSteps(achievementId,3); }else { performSetStepsImmediate(client,achievementId,3); } } private void performSetStepsImmediate(AchievementsClient client, String achievementId, int stepsNum) { Task<Boolean> task = client.makeStepsWithResult(achievementId, stepsNum); task.addOnSuccessListener(new OnSuccessListener<Boolean>() { @Override public void onSuccess(Boolean isSucess) { if (isSucess) { showLog("setAchievementSteps isSucess"); } else { showLog("achievement can not makeSteps"); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog("step num is invalid"+result); } } }); }

Step 6 Unlock an achievement.

@Override public void Unlock(String achievementId, boolean isChecked) { if (!isChecked){ client.reach(achievementId); }else { performUnlockImmediate(client,achievementId); } } private void performUnlockImmediate(AchievementsClient client, String achievementId) { Task<Void> task = client.reachWithResult(achievementId); task.addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void v) { showLog("UnlockAchievemen isSucess"); requestData(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { if (e instanceof ApiException) { String result = "rtnCode:" + ((ApiException) e).getStatusCode(); showLog("achievement has been already unlocked"+result); } } }); }
  1. Add your HUAWEI ID as a tester account by referring to Creating a Tester Account.
  2. Run your Android Studio project and generate the APK. Then, install the APK on your mobile phone for testing.
  3. Test the game sign-in.
  4. Click InitSignIn and GetCurrentPlayer in the main page to check if it works.

  5. Test the game sign-in and achievement functions
  6. Click on the LoadAchievement button on the home page and test whether you can display the list of achievements.

    Click on the achievement icon to see if you can display the details of your achievements.

    Click Unlock,IncrementSteps and SetSteps to test the other features.

Congratulations! You have successfully built your first game app and learned:

Introduction to Achievements

Game APIs

You can download the source code in github.com/Huawei/Consumer/tree/master/Codelabs/GameService

You can also click the button below to download the source code.

Download Source Code

Code copied