[Huawei Developers] Freemind R:
This article is originally from HUAWEI Developer Forum.

Forum link: https://forums.developer.huawei.com/forumPortal/en/home

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175736.51207402989350544764919571829736:50510525012332:2800:837341E8FC41423601C4BC4A6392CA5F1CED12AD2F874993ED625ADC9BF690F8.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175736.51207402989350544764919571829736:50510525012332:2800:837341E8FC41423601C4BC4A6392CA5F1CED12AD2F874993ED625ADC9BF690F8.png[/IMG]​

Huawei Ads provide developers an extensive data capabilities to deliver high quality ad content to their users. By integrating HMS ads kit we can start earning right away. It is very useful particularly when we are publishing a free app and want to earn some money from it.

Integrating HMS ads kit does not take more than 10 mins. HMS ads kit currently offers five types of ad format:

v Banner Ad: Banner ads are rectangular images that occupy a spot at the top, middle, or bottom within an app's layout. Banner ads refresh automatically at regular intervals. When a user taps a banner ad, the user is redirected to the advertiser's page in most cases.

v Native Ad: Native ads fit seamlessly into the surrounding content to match our app design. Such ads can be customized as needed.

v Reward Ad: Rewarded ads are full-screen video ads that reward users for watching.

v Interstitial Ad: Interstitial ads are full-screen ads that cover the interface of an app. Such ads are displayed when a user starts, pauses, or exits an app, without disrupting the user's experience.

v Splash Ad: Splash ads are displayed immediately after an app is launched, even before the home screen of the app is displayed.

Today in this article we are going to learn how to integrate Reward Ad into our apps.

Prerequisite

1) Must have a Huawei Developer Account

2) Must have a Huawei phone with HMS 4.0.0.300 or later

3) Must have a laptop or desktop with Android Studio , Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175820.67011531686125875430110083081414:50510525012332:2800:6E4570533B2A9D98074ED1BCCB0D3B65161D8C1587F27E8317DB78E0FB969DCA.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175820.67011531686125875430110083081414:50510525012332:2800:6E4570533B2A9D98074ED1BCCB0D3B65161D8C1587F27E8317DB78E0FB969DCA.png[/IMG]​

Things Need To Be Done

1) First we need to create a project in android studio.

2) Get the SHA Key. For getting the SHA key we can refer to this article.

3) Create an app in the Huawei app gallery connect.

4) Provide the SHA Key in App Information Section.

5) Provide storage location.

6) 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.

7) Copy and paste the below maven url inside the repositories of buildscript and allprojects ( project build.gradle file )

maven { url 'http://developer.huawei.com/repo/' }

8) Copy and paste the below plugin in the app build.gradle file dependencies section.

implementation 'com.huawei.hms:ads-lite:13.4.28.305'

9) If the project is using progaurd, copy and paste the below code in the progaurd-rules.pro file.

-keep class com.huawei.openalliance.ad.** { *; }
-keep class com.huawei.hms.ads.** { *; }

10) The HUAWEI Ads SDK requires the following permissions:

a) android.permission.ACCESS_NETWORK_STATE

b) android.permission.ACCESS_WIFI_STATE

11) Now sync the app.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175943.62281015137538771572785429771576:50510525012332:2800:35D4A9D977366B3AD93EAD2290FF0FC1A0C08DC453B882363F5A6CA87EB9C91B.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200413175943.62281015137538771572785429771576:50510525012332:2800:35D4A9D977366B3AD93EAD2290FF0FC1A0C08DC453B882363F5A6CA87EB9C91B.gif[/IMG]​

There are two ways we can use Reward Ad in to our aps.

1. Showing Reward ad after splash screen.

2. Using Reward ad in a game.

Reward Ad after splash screen

In this scenario, we will show reward ad after displaying few seconds of splash screen.

STEPS

1) Create a RewardAd Object and use it call loadAd() method to load an Ad. Place it in onCreate() method.

private void loadRewardAd() {
if (rewardAd == null) {
rewardAd = new RewardAd(SplashActivity.this, AD_ID);
}
RewardAdLoadListener listener= new RewardAdLoadListener() {
@Override
public void onRewardedLoaded() {
// Rewarded ad loaded successfully...
}
@Override
public void onRewardAdFailedToLoad(int errorCode) {
// Failed to load the rewarded ad...
}
};
rewardAd.loadAd(new AdParam.Builder().build(),listener);
}

2) Call the isLoaded() method to confirm that an ad has finished loading, and call the show() method of the RewardAd object to display the ad.

private void rewardAdShow() {

if(rewardAd.isLoaded()) {
rewardAd.show(SplashActivity.this, new RewardAdStatusListener() {
@Override
public void onRewardAdClosed() {
super.onRewardAdClosed();
goToMainPage();
}

@Override
public void onRewardAdFailedToShow(int i) {
super.onRewardAdFailedToShow(i);
goToMainPage();
}

@Override
public void onRewardAdOpened() {
super.onRewardAdOpened();
}

@Override
public void onRewarded(Reward reward) {
super.onRewarded(reward);
goToMainPage();
}
});
}
else{
goToMainPage();
}

}

3) A handler to call rewardAdShow() method after few seconds. Place it in the onCreate() method after loadRewardAd() method.

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
rewardAdShow();
}
}, 1000);

4) When testing rewarded ads, use the dedicated test ad slot ID to obtain test ads. This avoids invalid ad clicks during the test. The test ad slot ID is used only for function commissioning. Before releasing your app, apply for a formal ad slot ID and replace the test ad slot ID with the formal one.

THE RESULT

​

Reward Ad in a Game

In this scenario, we will show Reward Ad in a game and how user will get rewards after watching the ad. In real scenario user gets rewards in terms of extra coins, advance weapon, extra bullets for a weapon, extra life etc.

Here we will showcase how user gets extra life in a game after watching Reward Ad. The name of the game is Luck By Chance.

GAME RULES

· The game will generate a random number between 1 - 1000.

· The player needs to guess that number.

· Suppose the number is 200, the player guess the number as 190. Then the game will let the player know that the number is too low.

· If the player guess the number as 210. Then the game will let the player know that the number is too high.

· The player gets 3 life that means the player has 3 chance to guess the number right.

· If the player exhaust his / her 3 life then the game will give a chance to the player to watch Reward Ad video to get an extra life i.e. 1 life.

· After watching the Reward Ad video player can play one more chance and if the player guess it right then he / she wins the game.

· If the player wins the game, the player gets 5 score. The score gets added by 5 each time the player wins the game.

STEPS

1) Generate Random Number

public static final int MAX_NUMBER = 1000;
public static final Random RANDOM = new Random();

private void newGamePlay() {
findTheNumber = RANDOM.nextInt(MAX_NUMBER) + 5;
edtGuessNumber.setText("");
if (!blnScore) {
numScore = 0;
}
txtScore.setText("Score " + numScore);
numberTries = 3;
setLife(numberTries);

}

2) Create a method to play the game. Here we will check whether the guess number is too high or too low and if the user guess it right then we will show a win message to the user.

private void playTheGame() {
int guessNumber = Integer.parseInt(edtGuessNumber.getText().toString());

if (numberTries <= 0) {
showAdDialog();
} else {
if (guessNumber == findTheNumber) {
txtResult.setText("Congratulations ! You found the number " + findTheNumber);
numScore +=5;
blnScore = true;
newGamePlay();
} else if (guessNumber > findTheNumber) {
numberTries--;
setLife(numberTries);
if(numScore >0) {
numScore -= 1;
}
txtResult.setText(R.string.high);
} else {
numberTries--;
setLife(numberTries);
if(numScore >0) {
numScore -= 1;
}
txtResult.setText(R.string.low);
}
}
}

3) Create a RewardAd Object and use it call loadAd() method to load an Ad. Place it in onCreate() method.

private void loadRewardAd() {
if (rewardedAd == null) {
rewardedAd = new RewardAd(RewardActivity.this, AD_ID);
}

RewardAdLoadListener rewardAdLoadListener = new RewardAdLoadListener() {
@Override
public void onRewardAdFailedToLoad(int errorCode) {
Toast.makeText(RewardActivity.this,
"onRewardAdFailedToLoad "
+ "errorCode is :"
+ errorCode, Toast.LENGTH_SHORT).show();
}

@Override
public void onRewardedLoaded() {
}
};

rewardedAd.loadAd(new AdParam.Builder().build(), rewardAdLoadListener);
}

4) Call the isLoaded() method to confirm that an ad has finished loading, and call the show() method of the RewardAd object to display the ad. After user watch the entire Reward Ad video, he/she will get extra life i.e. 1.

private void rewardAdShow() {
if (rewardedAd.isLoaded()) {
rewardedAd.show(RewardActivity.this, new RewardAdStatusListener() {
@Override
public void onRewardAdClosed() {
loadRewardAd();
}

@Override
public void onRewardAdFailedToShow(int errorCode) {
Toast.makeText(RewardActivity.this,
"onRewardAdFailedToShow "
+ "errorCode is :"
+ errorCode,
Toast.LENGTH_SHORT).show();
}

@Override
public void onRewardAdOpened() {
Toast.makeText(RewardActivity.this,
"onRewardAdOpened",
Toast.LENGTH_SHORT).show();
}

@Override
public void onRewarded(Reward reward) {
numberTries ++; // HERE USER WILL GET REWARD AFTER WATCHING REWARD Ad VIDEO ...
setLife(numberTries);
}
});
}
}

5) A dialog to show the user that he/she needs to watch the video to get extra life. Here we will call rewardAdShow() method to show the reward video to the user for extra life if he/she accept to continue the game.

private void showAdDialog() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("GET EXTRA LIFE");
alertDialogBuilder
.setMessage("Watch video to get extra life")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

rewardAdShow();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});

AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}

THE CODE

RewardActivity.java

public class RewardActivity extends AppCompatActivity implements View.OnClickListener {

public static final int MAX_NUMBER = 1000;
public static final Random RANDOM = new Random();
private static final String AD_ID = "testx9dtjwj8hp";
TextView txtHeader, txtScore, txtLife, txtResult;
EditText edtGuessNumber;
Button btnGuess;
boolean blnScore = false;
private int findTheNumber, numberTries, numScore = 1;
private RewardAd rewardedAd;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reward);
txtHeader = findViewById(R.id.txtHeader);
txtHeader.setText("LUCK BY CHANCE");
txtLife = findViewById(R.id.txtLife);
txtScore = findViewById(R.id.txtScore);
txtResult = findViewById(R.id.txtStatus);
edtGuessNumber = findViewById(R.id.edtGuessNumber);
btnGuess = findViewById(R.id.btnGuess);
btnGuess.setOnClickListener(this);
newGamePlay();
loadRewardAd();
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnGuess:
playTheGame();
break;
}
}

@SuppressLint("SetTextI18n")
private void playTheGame() {
int guessNumber = Integer.parseInt(edtGuessNumber.getText().toString());

if (numberTries <= 0) {
showAdDialog();
} else {
if (guessNumber == findTheNumber) {
txtResult.setText("Congratulations ! You found the number " + findTheNumber);
numScore +=5;
blnScore = true;
newGamePlay();
} else if (guessNumber > findTheNumber) {
numberTries--;
setLife(numberTries);
if(numScore >0) {
numScore -= 1;
}
txtResult.setText(R.string.high);
} else {
numberTries--;
setLife(numberTries);
if(numScore >0) {
numScore -= 1;
}
txtResult.setText(R.string.low);
}
}
}

private void showAdDialog() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("GET EXTRA LIFE");
alertDialogBuilder
.setMessage("Watch video to get extra life")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

rewardAdShow();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});

AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}

@SuppressLint("SetTextI18n")
private void newGamePlay() {
findTheNumber = RANDOM.nextInt(MAX_NUMBER) + 5;
edtGuessNumber.setText("");
if (!blnScore) {
numScore = 0;
}
txtScore.setText("Score " + numScore);
numberTries = 3;
setLife(numberTries);

}

private void loadRewardAd() {
if (rewardedAd == null) {
rewardedAd = new RewardAd(RewardActivity.this, AD_ID);
}

RewardAdLoadListener rewardAdLoadListener = new RewardAdLoadListener() {
@Override
public void onRewardAdFailedToLoad(int errorCode) {
Toast.makeText(RewardActivity.this,
"onRewardAdFailedToLoad "
+ "errorCode is :"
+ errorCode, Toast.LENGTH_SHORT).show();
}

@Override
public void onRewardedLoaded() {
}
};

rewardedAd.loadAd(new AdParam.Builder().build(), rewardAdLoadListener);
}

private void rewardAdShow() {
if (rewardedAd.isLoaded()) {
rewardedAd.show(RewardActivity.this, new RewardAdStatusListener() {
@Override
public void onRewardAdClosed() {
loadRewardAd();
}

@Override
public void onRewardAdFailedToShow(int errorCode) {
Toast.makeText(RewardActivity.this,
"onRewardAdFailedToShow "
+ "errorCode is :"
+ errorCode,
Toast.LENGTH_SHORT).show();
}

@Override
public void onRewardAdOpened() {
Toast.makeText(RewardActivity.this,
"onRewardAdOpened",
Toast.LENGTH_SHORT).show();
}

@Override
public void onRewarded(Reward reward) {
numberTries ++;
setLife(numberTries);
}
});
}
}
private void setLife(int life) {
txtLife.setText("Life " + life);
}
}

activity_reward.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RewardActivity">

<include
android:id="@+id/include"
layout="@layout/layout_bar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<EditText
android:id="@+id/edtGuessNumber"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="32dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="32dp"
android:background="@drawable/edittext_style"
android:ems="10"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:inputType="number|none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3"
app:layout_constraintVertical_bias="0.0" />

<TextView
android:id="@+id/txtLife"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
android:textColor="#0B400F"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"
app:layout_constraintVertical_bias="0.00999999" />

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="200dp"
android:text="Guess The Number ?"
android:textColor="#3040E4"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"
app:layout_constraintVertical_bias="0.0" />

<Button
android:id="@+id/btnGuess"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="32dp"
android:layout_marginTop="70dp"
android:layout_marginEnd="32dp"
android:background="#F57F17"
android:text="@string/play"
android:textColor="#FFFFFF"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edtGuessNumber"
app:layout_constraintVertical_bias="0.0" />

<TextView
android:id="@+id/txtStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:textColor="#1B5E20"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edtGuessNumber"
app:layout_constraintVertical_bias="0.0" />

<TextView
android:id="@+id/txtScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="32dp"
android:text="Score 0"
android:textColor="#B71C1C"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/textView3"
app:layout_constraintEnd_toStartOf="@+id/txtLife"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include"
app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.widget.ConstraintLayout>

THE RESULT

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200429100739.46788285461849093256187687108905:50510525012332:2800:7F1626002829282B16B33BA0DB3F6B3F2D96B9A906566A8E79BF60C6B395057C.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/647/156/2640091000001647156.20200429100739.46788285461849093256187687108905:50510525012332:2800:7F1626002829282B16B33BA0DB3F6B3F2D96B9A906566A8E79BF60C6B395057C.gif[/IMG]​