激勵廣告
激勵廣告是一種全屏幕的視頻廣告,用戶可以選擇點擊觀看,以換取相應(yīng)獎勵。
添加激勵廣告
1.創(chuàng)建激勵廣告對象。
創(chuàng)建RewardAd對象,示例代碼如下:
public class RewardedVideoActivity extends Activity {
// "testx9dtjwj8hp"為專用的測試廣告位ID,App正式發(fā)布時需要改為正式的廣告位ID
private static final String AD_ID = "testx9dtjwj8hp";
private RewardAd rewardAd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rewarded);
// 創(chuàng)建激勵廣告對象
createRewardAd();
}
private void createRewardAd() {
rewardAd = new RewardAd(this, AD_ID);
}
}
2.獲取廣告。
調(diào)用RewardAd對象的loadAd()方法來獲取廣告,示例代碼如下:
/**
* 加載激勵廣告
*/
private void loadRewardAd() {
if (rewardAd == null) {
rewardAd = new RewardAd(this, AD_ID);
}
RewardAdLoadListener listener= new RewardAdLoadListener() {
@Override
public void onRewardedLoaded() {
// 激勵廣告加載成功
}
@Override
public void onRewardAdFailedToLoad(int errorCode) {
// 激勵廣告加載失敗
}
};
rewardAd.loadAd(new AdParam.Builder().build(), listener);
}
3.展示廣告。
調(diào)用RewardAd的show()方法來顯示廣告,在此之前需要調(diào)用isLoaded()方法來確認(rèn)廣告已經(jīng)加載完成。
如下所示:
/**
* 展示激勵廣告
*/
private void rewardAdShow() {
if (rewardAd.isLoaded()) {
rewardAd.show(RewardedVideoActivity.this, new RewardAdStatusListener() {
@Override
public void onRewardAdOpened() {
// 激勵廣告被打開
...
}
@Override
public void onRewardAdFailedToShow(int errorCode) {
// 激勵廣告展示失敗
...
}
@Override
public void onRewardAdClosed() {
// 激勵廣告被關(guān)閉
...
}
@Override
public void onRewarded(Reward reward){
// 激勵廣告獎勵達(dá)成,發(fā)放獎勵
...
}
});
}
}
說明
onRewarded方法中,如果在廣告位配置了獎勵物品信息,則會傳入獎勵物品信息的對象reward,通過reward.getAmount()方法獲取獎勵物品的數(shù)量,通過reward.getName()方法獲取獎勵物品的名稱,推薦立即發(fā)放獎勵,同時在服務(wù)端做校驗,判斷獎勵是否生效。如果未配置獎勵物品信息,則根據(jù)實際場景發(fā)放獎勵。
測試激勵廣告
測試激勵廣告時,需要使用專門的測試廣告位ID來獲取測試廣告,以避免在測試過程中產(chǎn)生無效的廣告點擊量。測試廣告位ID僅作為功能調(diào)試使用,不可用于廣告變現(xiàn)。您需要在應(yīng)用發(fā)布前申請真實的廣告位ID,并替換測試廣告位ID。
以下表格中提供了激勵廣告的專用測試廣告位ID:
下載激勵廣告的示例代碼并運行,可以看到如下效果圖:
另外您也可以通過學(xué)習(xí)Codelab中的教程來集成激勵廣告。
校驗激勵廣告服務(wù)端驗證回調(diào)
服務(wù)端驗證回調(diào)是指HUAWEI Ads廣告平臺發(fā)送給媒體服務(wù)器的網(wǎng)址請求,其中帶有特定的查詢參數(shù),用來通知媒體服務(wù)器某位用戶因為與激勵視頻廣告互動而應(yīng)予以獎勵,從而規(guī)避欺騙的行為。
獎勵用戶
·在給用戶發(fā)獎勵時,要把握好用戶體驗和獎勵驗證之間的平衡。因為服務(wù)器端回調(diào),可能會出現(xiàn)延遲,因此我們建議客戶端立即獎勵用戶,同時在收到服務(wù)器端回調(diào)時對所有獎勵進(jìn)行驗證。這種做法可確保獎勵符合發(fā)放條件,同時提供良好的用戶體驗。
·對于某些應(yīng)用而言,獎勵是否達(dá)到發(fā)放條件非常重要,用戶可適當(dāng)接受延遲。這時,最佳做法是等待服務(wù)器端回調(diào)完成驗證,再向用戶發(fā)放獎勵。
校驗服務(wù)端驗證回調(diào)
1.設(shè)置激勵廣告的獎勵配置。
您在HUAWEI Ads媒體服務(wù)平臺上申請激勵視頻廣告位時選擇“媒體管理(點擊媒體名)>新增展示位>選擇激勵視頻(點擊下一步,進(jìn)入編輯頁面)”,設(shè)置獎勵類型和獎勵數(shù)量,并點擊“高級設(shè)置”,設(shè)置服務(wù)器端驗證的URL。如下圖:
2.(可選)設(shè)置自定義數(shù)據(jù)和userId。
您在App中請求激勵廣告之前對激勵廣告對象設(shè)置自定義數(shù)據(jù)data和userId。
RewardAd rewardAd = new RewardAd(RewardActivity.this, getString(R.string.ad_id_reward));
RewardVerifyConfig config = new RewardVerifyConfig.Builder().setData("CUSTOM_DATA")
.setUserId("1234567")
.build();
rewardAd.setRewardVerifyConfig(config);
...
rewardAd.loadAd(new AdParam.Builder().build(), rewardAdLoadListener);
說明
如果沒有設(shè)置data和userId,不影響發(fā)放獎勵事件上報但是服務(wù)端驗證的參數(shù)中沒有這兩個字段。如果設(shè)置data和userId,必須在展示廣告之前設(shè)置并且URLEncode之后,長度不超過1024個字符,否則影響服務(wù)端驗證。
3.獲取要驗證的內(nèi)容。
用戶觀看完激勵廣告時,HUAWEI Ads服務(wù)端會把需要驗證的參數(shù)以及KeyId和sign傳給媒體提供的URL: https://www.example.com/feedback(即步驟一中配置的驗證URL)。請求體:
{
"adId" : "testx9dtjwj8hp",
"data" : "CUSTOM_DATA",
"keyId" : "12345678",
"rewardAmount" : "10",
"rewardName" : "金幣",
"sign" : "OA33u6mypnhE4hbmF32N/ibYi1uXt72nDDyYMwjDI6JXVVFKePZYo4F7Fuk2MaG......",
"uniqueId" : "3361626337333932313435313430373438383561376265636130393939313166",
"userId" : "1234567"
}
服務(wù)器端驗證回調(diào)查詢參數(shù)說明:
4.組裝驗證參數(shù)。
驗證內(nèi)容(除sign、keyId)格式順序如下:
adId={adId}&data={data}&rewardAmount={rewardAmount}&rewardName={rewardName}&uniqueId={uniqueId}&userId={userId}
其中‘{}’里面表示參數(shù)的值,且參數(shù)順序不能變。假如參數(shù)為null或者空字符串,則url中不拼接該參數(shù),然后用sha256計算散列值,得到paramContentData。
示例代碼如下:
String adId = request.getParameter("adId");
String data = request.getParameter("data");
String userId = request.getParameter("userId");
String param = "adId=" + adId + "&data=" + data + "&rewardAmount=" + rewardAmount + "&rewardName=" + rewardName + "&uniqueId=" + uniqueId + "&userId=" + userId;
String sha256Value = Sha256Util.digest(param);
byte[] paramContentData = sha256Value.getBytes(Charset.forName("UTF-8"));
5.獲取公鑰列表。
1.在HUAWEI Ads 媒體服務(wù)平臺查看對應(yīng)的激勵視頻廣告位,點擊“獲取密鑰”按鈕獲取“開發(fā)者ID”和“密鑰”:
2. 通過如下接口獲得華為提供的公鑰列表:
接口URL:https://ppscrowd-dre.op.dbankcloud.com/action-lib-track/publickeys
將body通過密鑰進(jìn)行HMAC-SHA256加密得到簽名,替換到Authorization中,并設(shè)置“開發(fā)者ID”和Authorization到Header中。
示例代碼如下:
String data = "";
String url = "https://ppscrowd-dre.op.dbankcloud.com/action-lib-track/publickeys";
String authorization = "Digest validTime=\"{0}\", response=\"{1}\"";
// 開發(fā)者ID
String userId = "YOUR_PUBLISHER_ID";
// 密鑰
String key = "YOUR_KEY";
HttpClient httpclient = HttpClients.createDefault();
HttpGet request = new HttpGet();
try {
String validTime = String.valueOf(System.currentTimeMillis());
String body = validTime + ":/publickeys";
byte[] keyBytes = Base64.decodeBase64(key);
byte[] bodyBytes = body.getBytes(Charsets.UTF_8);
Mac mac = Mac.getInstance("HmacSHA256");
SecretKey secretKey = new SecretKeySpec(keyBytes, "HmacSHA256");
mac.init(secretKey);
byte[] signatureBytes = mac.doFinal(bodyBytes);
String signature = (signatureBytes == null) ? null : Hex.encodeHexString(signatureBytes);
authorization = MessageFormat.format(authorization, validTime, signature);
request.setURI(new URI(url));
request.setHeader("userId", userId);
request.setHeader("Authorization", authorization);
HttpResponse response = httpclient.execute(request);
data = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
}
}
返回data消息體:
{
"keys": [
{
"keyId":"12345678",
"publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1GLi4uc3c9PVxkQgUFVCTElt"
},
{
"keyId": "22345678",
"publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1GLi4uc3c9PVxkQgUFVCTElt"
}
]
}
返回消息結(jié)構(gòu)體:
Key結(jié)構(gòu)體:
6.執(zhí)行驗證。
a.根據(jù)keyId從公鑰列表中找到對應(yīng)的base64編碼后的publicKey。
b.然后將paramContentData、publicKey和sign作為SHA256withRSA數(shù)字簽名算法的入?yún)?,?zhí)行驗證。
示例代碼如下:
public static boolean verify(byte[] data, String publicKey, String sign, String signatureAlgorithm) {
try {
byte[] keyBytes = base64Decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(signatureAlgorithm);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(base64Decode(sign));
} catch (InvalidKeyException | SignatureException | UnsupportedEncodingException | InvalidKeySpecException | NoSuchAlgorithmException e) {
return false;
}
}
private static byte[] base64Decode(String encoded) throws UnsupportedEncodingException {
return Base64.decodeBase64(encoded.getBytes("UTF-8"));
}