‹ HMS Doc Home

HMS 集成指南

For the Javascript version of cocos2d-x v3.x - (all other versions)

集成

用如下命令来集成 SDKBOX HMS 插件,请确保您可以正常执行的 SDKBOX 安装器.

sdkbox import hms

重点注意事项

如果您升级到了 Xcode7, 则需要以下额外步骤来确保插件工作正常:

禁用应用程序安全传输策略

添加以下项到 plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

添加后的文件内容看起来就像这样:

禁止 Bitcode 支持

您必须禁止 Bitcode 的支持,否则将会编译失败。

游戏全屏配置

如果您的游戏不同时支持横竖屏,则必须在 Xcode 中选中 Requires full screen,否则将不会通过 Apple 的审核。

canOpenURL 白名单

取决于您使用哪些插件。需要在 info.plistLSApplicationQueriesSchemes 下添加名单。

关于 Creator 工程

Creator 导出工程会修改工程的配置, 这可能会影响 SDKBox 对工程的配置修改. 所以可以有以下做法(任选其一):

  1. 保存导出工程中的修改, 对于 SDKBox 来说可能有这些文件(mk, gradle, gradle.properties, AppDelegate.cpp, ...), 导出后再恢复对应该文件
  2. 在每一次 Creator 导出工程后, 重新 import 插件.

推荐第一种, 但是第一种的麻烦点在于, 对于第一次(或很久没接触的人)可能会有露掉某个文件 第二种, 很方便, 它的麻烦点在于, 如果你对工程有自己的修改, SDKBox 的重新 import 不能帮你恢复.

额外步骤

Android步骤

你应该在 Application::onCreate 中添加这一行代码 com.sdkbox.plugin.PluginHMS.ApplicationInit(this); . 如下是一个修改的样例 (如果你的工程没有 Application 类, 那么请创建一个):

public class YourApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        com.sdkbox.plugin.PluginHMS.ApplicationInit(this); // 添加这一行
    }

    ...
}

JSON 配置

SDKBOX 安装器会自动在您的工程中添加一个样例配置文件sdkbox_config.json.在您编译工程前,请修改里面的参数,用您自己的应用信息

这里HMS的配置样例.

"ios" :
{
    "hms":{
    }
},
"android":
{
    "hms":{
        "archive": true,
        "key": "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAn9U6yC1QI8cXGRkOQxO9QG/WV8dR4jZDCYt/GJBM4OTTtRZeAIEyVifGPutwMAkPBLgdUsJwHuA2t2jrBAi/nagYJvh8UIazKJv5C4Hykw5Z2iKTWMmiMK9rQ2tMtRTAMiY+LwfaOH2258bEyt8mDQxyG3aRSAH28mZki/nGEbNfx7ZY9By/SSkuaCEWRDNYdiWkGDuZLhf8D97DoJJc6tTnrDPmzf1QqkVDjjudkHJwgCMWpLVACzGGuo4YQYt98Pu9cqbiYWJqSHqEbPYN0AmGXdJw+tO5f1wPcZWnJhn4JqCFmD9i/dSENNJWXVDgJc0DG2PiWX5j+qUaT7WkZMs4/WFtL6VRdRUDzITqYwKUUBYENVvkfdKlhjh+6V4BFKPsipvjOsRdXDpZ7sC6MY/7yn0eMOH3RoIQoiWeGYkxRTkKhdm/QQ/Xv/dvMbiicsNmUIkBce3w4hQG9XlhgjNrl5rI4p9Ho3Stq48s7DJlhWuUE6pXcjo2TJUSJ9+nAgMBAAE=",
        "items": {
            "remove_ads": {
                "type": "non_consumable",
                "id": "com.sdkbox.test.app.sample.noad"
            },
            "coin": {
                "id": "com.sdkbox.test.app.sample.coin1"
            },
            "vip": {
                "type": "subs",
                "id": "com.sdkbox.test.app.sample.vip"
            }
        },
        "achievements": [{
            "name": "freshman",
            "id": "A7346279E90AB8910AAC0CB71E552BFA2505DFD7591C79457F84D6B95F50FFEC",
            "incremental": false
        }, {
            "name": "3shoot",
            "id": "BA8B1A486D422AEF28FF82F9BFF85C3F156824396E0BB62D92BECC63C3CAC46A",
            "incremental": true
        }, {
            "name": "5shoot",
            "id": "001D38EC9E1A80A52ED3F47BFBA35F4B5BDF3776180A2B9AD778800C45CD6540",
            "incremental": true
        }],
        "events": [{
            "name": "gencoin",
            "id": "912764D10F0988B9DCB041A4E6FE453BCBDEDC4E35708A60E33C2DEBF05F2D2E"
        }, {
            "name": "consumecoin",
            "id": "E8688F3D9625572F462F5999E7F83EB5628E0FC1F2044E84D026EC4AB33C09F5"
        }],
        "rankings": [{
            "name": "shooter",
            "id": "C8B96FA1EDFC2D87DFE9491409440E3F8B2E39AFB8BD7E95C3BE337FC207C253"
        }]
    }
}

同时你还需要在 HMS 的 AppGallery 里将对应的应用信息文件 agconnect-services.json 下载下来,并放在应用工程目录下(一般来说是在 proj.android/app 目录).

iOS 测试

Android 测试

  1. 在 AppGallery 中创建一个 app
  2. 启起你想要使用的模块(比如你要使用登录, 就可以启用AccountKit)
  3. 添加app的签名hash
  4. 下载应用的信息文件 agconnect-services.json

HMS 的官方文档

使用

初始化 HMS

sdkbox.PluginHMS.init();
#include "PluginHMSJS.hpp"
#include "PluginHMSJSHelper.h"
sc->addRegisterCallback(register_all_PluginHMSJS);
sc->addRegisterCallback(register_all_PluginHMSJS_helper);

登录

HMS 提供了三种登录方式:

sdkbox.PluginHMS.login(1);
sdkbox.PluginHMS.login(2);

静默登录只能在上一次使用前两种方式已经登录成功的情况下,才能在静态登录下成功

sdkbox.PluginHMS.login(0);

以上三种登录方式, 不管成功还是失败, 最终都会触发 onLogin 事件.

HMS 帐号相关的 文档

登出

sdkbox.PluginHMS.logout();

请求托管在 HMS 的商品

托管商品是指在 HMS 管理后台配置的商品.

sdkbox.PluginHMS.iapRequestProducts();

这个方法会触发 Listener 中的 onIAPProducts 方法

购买托管商品

sdkbox.PluginHMS.iapPurchase("coin");

这个方法会触发 Listener 中的 onIAPPurchase 方法

购买非托管商品

非托管商品是指未在 HMS 后台配置商品, 但使用 HMS IAP 的来支付.

let productInfo = {
  priceType: 0, // 0:consumable 1:non-consumable 2:subscription
  productName: 'product name',
  productId: 'product id',
  amount: '1.00',
  currency: 'CNY',
  country: 'CN',
  sdkChannel: '1', // sdkChannel size must be between 0 and 4
  serviceCatalog: 'X58',
  reservedInfor: '{"a": 1, "b":"s"}', // reservedInfor must be json string
  developerPayload: 'payload1'
};
sdkbox.PluginHMS.iapPurchaseWithPrice(JSON.stringify(productInfo));

这个方法会触发 Listener 中的 onIAPPurchase 方法

请求拥有的商品

请求当前拥有的商品的购买记录, 包括 不可消费,订阅商品 和 非消费的可消费商品.

sdkbox.PluginHMS.iapRequestOwnedPurchases();

这个方法会触发 Listener 中的 onIAPOwnedPurchases 方法

消费商品

注意: 这里传的是 purchaseToken , 非不是商品名字或id

sdkbox.PluginHMS.iapConsume(purchaseToken);

这个方法会触发 Listener 中的 onIAPPConsume 方法

请求所有的消费记录

请求用户所有的消费记录

sdkbox.PluginHMS.iapRequestOwnedPurchaseRecords(purchaseToken);

这个方法会触发 Listener 中的 onIAPOwnedPurchaseRecords 方法

玩家信息

获取玩家信息

将会触发 Listener 中的函数 onPlayerInfo

sdkbox.PluginHMS.playerRequestInfo();

获取玩家额外信息

这里主要是针对 未成年防沉迷 机制, 可以取得玩家是否未成年人,它的游戏时间等信息, 开发者利用这些信息对防沉迷作相应处理.

将会触发 Listener 中的函数 onPlayerExtraInfo

sdkbox.PluginHMS.playerRequestInfo();

提交游戏开始

提交玩家开始游戏事件

将会触发 Listener 中的函数 onPlayerGameBegin

sdkbox.PluginHMS.playerSubmitGameBegin();

提交游戏结束

提交玩家结束游戏事件

将会触发 Listener 中的函数 onPlayerGameEnd

sdkbox.PluginHMS.playerSubmitGameEnd();

成就

取成就列表

获取成就列表, 开发者可以使用返回的数据来自行展示

将会触发 Listener 中的函数 onAchievementList

sdkbox.PluginHMS.achievementRequestList();

显示成就

使用华为默认的成就显示列表

将会触发 Listener 中的函数 onAchievementShow

sdkbox.PluginHMS.achievementShow();

成就可见

将会触发 Listener 中的函数 onAchievementVisualize

sdkbox.PluginHMS.achievementVisualize();

增长成就

将会触发 Listener 中的函数 onAchievementGrow

sdkbox.PluginHMS.achievementGrow();

设置成就步骤

将会触发 Listener 中的函数 onAchievementMakeSteps

sdkbox.PluginHMS.achievementMakeSteps();

解锁成就

sdkbox.PluginHMS.achievementReach();

事件

增长事件

sdkbox.PluginHMS.eventGrow(event, amount);

eventRequestList

将会触发 Listener 中的函数 onEventList

sdkbox.PluginHMS.eventRequestList();

排行榜

检查排行榜状态

在进行排行榜相关api前,开发者必检查玩家是否允许上传分数.

将会触发 Listener 中的函数 onRankingSwitchStatus

sdkbox.PluginHMS.rankingRequestSwitchStatus();

将会触发 Listener 中的函数 onRankingSetSwitchStatus

int status = 0;
// 0: allow open score in ranking
// 1: not allow open score in ranking

sdkbox.PluginHMS.rankingSetSwitchStatus(int status);

提交分数

将会触发 Listener 中的函数 onRankingSubmitScore

sdkbox.PluginHMS.rankingSubmitScore(rankingName, score, score_unit);

显示排行榜

开发者自行显示

将会触发 Listener 中的函数 onRankingList

bool realtime = true; // true, will request data from hms server; false, will use local cache data
sdkbox.PluginHMS.rankingRequestList(realtime, rankingName);

用华为默认列表显示 (此方式必须保证玩家终端EMUI为9.0及以上版本,且必须安装10.3及以上版本的华为应用助手。)

将会触发 Listener 中的函数 onRankingShow

int timeDimension = 2; // 0-> day, 1-> week, 2-> all time
sdkbox.PluginHMS.rankingShow(timeDimension, rankingName);

取分数

当前玩家的分数

将会触发 Listener 中的函数 onRankingCurPlayerScore

int timeDimension = 2; // 0-> day, 1-> week, 2-> all time
sdkbox.PluginHMS.rankingRequestCurPlayerScore(rankingName, timeDimension);

取以玩家分数为中心的分数列表

将会触发 Listener 中的函数 onRankingPlayerCenteredScores

int timeDimension = 2; // 0-> day, 1-> week, 2-> all time
sdkbox.PluginHMS.rankingRequestPlayerCenteredScores(rankingName, timeDimension, realtime);

存档

新增存档

将会触发 Listener 中的函数 onArchiveAdd

const bmBytes; // Uint8Array, cover image data
const dataBytes; // Uint8Array, archive binary data

sdkbox.PluginHMS.archiveAdd(playedTime, progress, description, supportCache,
                               bmBytes, bmBytesType,
                               dataBytes);

更新存档

将会触发 Listener 中的函数 onArchiveUpdate

const bmBytes; // Uint8Array, cover image data
const dataBytes; // Uint8Array, archive binary data

sdkbox.PluginHMS.archiveUpdate(archiveId,
                          playedTime, progress, description,
                          bmBytes, bmBytesType,
                          dataBytes);

读存档

将会触发 Listener 中的函数 onArchiveLoad

int conflictPolicy = 3;
//-1 -> hms willn't hand conflict, 
//1  -> hms will resolved conflict by played time, 
//2  -> hms will resolved conflict by progress,
//3  -> hms will resolved conflict by last update time
sdkbox.PluginHMS.archiveLoad(archiveId, conflictPolicy);

浮标

如果你的游戏将在中国发行,那必须打开游戏浮标

sdkbox.PluginHMS.buoyShow();
//or
sdkbox.PluginHMS.buoyHide();

广告

缓存广告

sdkbox.PluginHMS.adCache(adName);

显示广告

if (sdkbox.PluginHMS.adIsAvailable(adName)) {
    sdkbox.PluginHMS.adShow(adName);
}

隐藏广告

sdkbox.PluginHMS.adHide(adName);

广告请求参数设置 (可选)

/*
  * 广告内容类型:
  *   "W"->适合幼儿及以上年龄段观众的内容
  *  "PI"->适合少儿及以上年龄段观众的内容
  *   "J"->适合青少年及以上年龄段观众的内容
  *   "A"->仅适合成年观众众的内容
  *    ""->未明确广告分级
  */
sdkbox.PluginHMS.adSetAdContentClassification("A");

/*
  * 面向未达到法定承诺年龄用户的设置:
  *  0->不按面向未达到法定承诺年龄用户的方式来处理广告请求
  *  1->按面向未达到法定承诺年龄用户的方式来处理广告请求
  * -1->不确定是否按面向未达到法定承诺年龄用户的方式来处理广告请求
  */
sdkbox.PluginHMS.adSetTagForUnderAgeOfPromise(0);

/*
* 面向儿童的设置:
*  0->不根据 COPPA 的规定来处理广告请求
*  1->根据 COPPA 的规定来处理广告请求
* -1->不确定是否根据 COPPA 的规定来处理广告请求
*/
sdkbox.PluginHMS.adSetTagForChildProtection(0);

/*
* 是否只请求非个性化广告
*  0->请求个性化广告和非个性化广告(默认);
*  1->只请求非个性化广告;
*/
sdkbox.PluginHMS.adSetNonPersonalizedAd(0);

奖励广告设置 (可选)

设置的奖励数据必须要URLEncode, 同时长度不超过1024个字符

// 奖励广告定制数据
sdkbox.PluginHMS.adSetRewardData("cdata");

// 奖励广告用户 id
sdkbox.PluginHMS.adSetRewardUserId("uid666");

处理HMS事件

您可以接收 HMS 事件, 不同事件对您的用户及 HMS 服务器做不同的处理.

所有的回调中都包含一个 code , 这值的含义可以参与如下 url :

这里单独列出常见的一些值的含义:

sdkbox.PluginHMS.setListener({
    // Account
    onLogin: function (code, msg) {
        // login event
    },

    // Player Info
    onPlayerInfo: function(code, errorOrJson) {
    },

    onPlayerExtraInfo: function(code, errorOrJson) {
    },

    onPlayerGameBegin: function(code, errorOrJson) {
    },

    onPlayerGameEnd: function(code, errorOrJson) {
    },

    // IAP
    onIAPReady: function(code, msg) {
        self.log('HMS Listener onIAPReady:' + code);
        cc.log(msg);
    },
    onIAPProducts: function(code, msg) {
        self.log('HMS Listener onIAPProducts:' + code);
        cc.log(msg);
    },
    onIAPPurchase: function(code, msg) {
        self.log('HMS Listener onIAPPurchase:' + code);
        cc.log(msg);
    },
    onIAPPConsume: function(code, msg) {
        self.log('HMS Listener onIAPPConsume:' + code);
        cc.log(msg);
    },
    onIAPOwnedPurchases: function(code, msg) {
        self.log('HMS Listener onIAPOwnedPurchases:' + code);
        cc.log(msg);
    },
    onIAPOwnedPurchaseRecords: function(code, msg) {
        self.log('HMS Listener onIAPOwnedPurchaseRecords:' + code);
        cc.log(msg);
    },

    // Achievement
    onAchievementList(code, errorOrJson) {
    }

    onAchievementShow(code, errorOrJson) {
    }

    onAchievementVisualize(code, errorOrJson) {
    }

    onAchievementGrow(code, errorOrJson) {
    }

    onAchievementMakeSteps(code, errorOrJson) {
    }

    // Event
    onEventList(code, errorOrJson) {
    }

    // Ranking
    onRankingSwitchStatus(code, errorOrJson) {
    }

    onRankingSetSwitchStatus(code, errorOrJson) {
    }

    onRankingSubmitScore(code, errorOrJson) {
    }

    onRankingShow(code, errorOrJson) {
    }

    onRankingList(code, errorOrJson) {
    }

    onRankingCurPlayerScore(code, errorOrJson) {
    }

    onRankingPlayerCenteredScores(code, errorOrJson) {
    }

    onRankingMoreScores(code, errorOrJson) {
    }

    onRankingTopScores(code, errorOrJson) {
    }

    // Archive
    onArchiveLimitThumbnailSize(code, errorOrJson) {
    }

    onArchiveLimitDetailsSize(code, errorOrJson) {
    }

    onArchiveAdd(code, errorOrJson) {
    }

    onArchiveShow(code, errorOrJson) {
    }

    onArchiveSummaryList(code, errorOrJson) {
    }

    onArchiveSelect(code, errorOrJson) {
    }

    onArchiveThumbnail(code, errorOrJson, coverData:Uint8Array) {
    }

    onArchiveUpdate(code, errorOrJson) {
    }

    onArchiveLoad(code, errorOrJson, contentData:Uint8Array) {
    }

    onArchiveRemove(code, errorOrJson) {
    }

    // Game Stats
    onGamePlayerStats(code, errorOrJson) {
    }

    onGameSummary(code, errorOrJson) {
    }

    // Ad
    onAdClose(code, errorOrJson) {
    }

    onAdFail(code, errorOrJson) {
    }

    onAdLeave(code, errorOrJson) {
    }

    onAdOpen(code, errorOrJson) {
    }

    onAdLoad(code, errorOrJson) {
    }

    onAdClick(code, errorOrJson) {
    }

    onAdImpression(code, errorOrJson) {
    }

    onAdReward(code, errorOrJson) {
    }

});

API Reference

Methods

sdkbox.PluginHMS.setGDPR(enabled);

Set GDPR

sdkbox.PluginHMS.init();

initialize the plugin instance.

sdkbox.PluginHMS.setListener(listener);

Set listener to listen for adcolony events

sdkbox.PluginHMS.login(loginType);

HMS provider three way to login loginType: 0, slient login 1, login with HuaweiID(ID Token) 2, login with HuaweID(Authorization Code)

sdkbox.PluginHMS.logout();

logout HMS

sdkbox.PluginHMS.playerRequestInfo();

request current player info

sdkbox.PluginHMS.playerRequestExtraInfo();

request player extra info

sdkbox.PluginHMS.playerSubmitGameBegin();

submit game begin event

sdkbox.PluginHMS.playerSubmitGameEnd();

submit game end event

sdkbox.PluginHMS.iapRequestProducts();
sdkbox.PluginHMS.iapPurchase(name);
sdkbox.PluginHMS.iapPurchaseWithPrice(productJson);
sdkbox.PluginHMS.iapRequestOwnedPurchases();
sdkbox.PluginHMS.iapConsume(purchaseToken);
sdkbox.PluginHMS.iapRequestOwnedPurchaseRecords();
sdkbox.PluginHMS.achievementRequestList();
sdkbox.PluginHMS.achievementShow();
sdkbox.PluginHMS.achievementVisualize(name);
sdkbox.PluginHMS.achievementGrow(achiveName, steps);
sdkbox.PluginHMS.achievementMakeSteps(achiveName, steps);
sdkbox.PluginHMS.achievementReach(achiveName);
sdkbox.PluginHMS.eventGrow(eventName, amount);
sdkbox.PluginHMS.eventRequestList(realtime, eventNamas);
sdkbox.PluginHMS.rankingRequestSwitchStatus();

request if player allow open score in ranking

sdkbox.PluginHMS.rankingSetSwitchStatus(status);

request if player allow open score in ranking status: 0->player allow submit score, 1->player not allow submit score

sdkbox.PluginHMS.rankingSubmitScore(rankingName, score, unit);

submit score to ranking

sdkbox.PluginHMS.rankingShow(timeDimension, rankingName);

use hms's ui to show ranking

sdkbox.PluginHMS.rankingRequestList(realtime, rankingName);

request ranking list

sdkbox.PluginHMS.rankingRequestCurPlayerScore(rankingName, timeDimension);

request current player ranking score

sdkbox.PluginHMS.rankingRequestPlayerCenteredScores(rankingName,
                                                     timeDimension,
                                                     size,
                                                     realtime);

request player centered scores

sdkbox.PluginHMS.rankingRequestMoreScores(rankingName,
                                           timeDimension,
                                           offset,
                                           pageSize,
                                           pageDirection);

request more scores

sdkbox.PluginHMS.rankingRequestTopScores(rankingName,
                                          timeDimension,
                                          offset,
                                          pageSize,
                                          pageDirection);

submit score to ranking

sdkbox.PluginHMS.archiveRequestLimitThumbnailSize();

get thumbnail max size

sdkbox.PluginHMS.archiveRequestLimitDetailsSize();

get detail max size

sdkbox.PluginHMS.archiveAdd(playedTime, progress, description, supportCache,
                               bmBytes, bmBytesType,
                               dataBytes)

add archive bmBytes: Uint8Array, cover image data dataBytes: Uint8Array, archive data

sdkbox.PluginHMS.archiveShow(title, allowAdd, allowDelete, pageSize);

use hms's default ui to show archive

sdkbox.PluginHMS.archiveRequestSummaryList(realtime);

request archive summay list, developer can show custome archive list with the returned data

sdkbox.PluginHMS.archiveRequestThumbnail(archiveId);

request archive cover thumbnail

sdkbox.PluginHMS.archiveUpdate(archiveId,
                               playedTime, progress, description, supportCache,
                               bmBytes, bmBytesType,
                               dataBytes)

update archive bmBytes: Uint8Array, cover image data dataBytes: Uint8Array, archive data

sdkbox.PluginHMS.archiveLoad(archiveId, conflictPolicy);

load archive

sdkbox.PluginHMS.archiveRemove(archiveId);

remvoe archive

sdkbox.PluginHMS.gamePlayerStatsRequest(realtime);

request game player statistics

sdkbox.PluginHMS.gameSummaryRequest(realtime);

request game summary

sdkbox.PluginHMS.buoyShow();
sdkbox.PluginHMS.buoyHide();
sdkbox.PluginHMS.adCache(name);
sdkbox.PluginHMS.adShow(name);
sdkbox.PluginHMS.adHide(name);
sdkbox.PluginHMS.adIsAvailable(name);
sdkbox.PluginHMS.adSetRewardData(custom_data);
sdkbox.PluginHMS.adSetRewardUserId(user_id);
sdkbox.PluginHMS.adSetAdContentClassification(adContentClassification);
sdkbox.PluginHMS.adSetTagForUnderAgeOfPromise(tagForUnderAgeOfPromise);
sdkbox.PluginHMS.adSetTagForChildProtection(tagForChildProtection);
sdkbox.PluginHMS.adSetNonPersonalizedAd(nonPersonalizedAd);

Listeners

onLogin(code, errorOrJson);
onPlayerInfo(code, errorOrJson);
onPlayerExtraInfo(code, errorOrJson);
onPlayerGameBegin(code, errorOrJson);
onPlayerGameEnd(code, errorOrJson);
onIAPReady(code, errorOrJson);
onIAPProducts(code, errorOrJson);
onIAPPurchase(code, errorOrJson);
onIAPConsume(code, errorOrJson);
onIAPOwnedPurchases(code, errorOrJson);
onIAPOwnedPurchaseRecords(code, errorOrJson);
onAchievementList(code, errorOrJson);
onAchievementShow(code, errorOrJson);
onAchievementVisualize(code, errorOrJson);
onAchievementGrow(code, errorOrJson);
onAchievementMakeSteps(code, errorOrJson);
onEventList(code, errorOrJson);
onRankingSwitchStatus(code, errorOrJson);
onRankingSetSwitchStatus(code, errorOrJson);
onRankingSubmitScore(code, errorOrJson);

callback for rankingSubmitScore

onRankingShow(code, errorOrJson);

callback for rankingShow

onRankingList(code, errorOrJson);

callback for rankingRequestList

onRankingCurPlayerScore(code, errorOrJson);

callback for rankingRequestCurPlayerScore

onRankingPlayerCenteredScores(code, errorOrJson);

callback for rankingRequestPlayerCenteredScores

onRankingMoreScores(code, errorOrJson);

callback for rankingRequestMoreScores

onRankingTopScores(code, errorOrJson);

callback for rankingRequestTopScores

onArchiveLimitThumbnailSize(code, errorOrJson);

callback for archiveRequestLimitThumbnailSize

onArchiveLimitDetailsSize(code, errorOrJson);

callback for archiveRequestLimitDetailsSize

onArchiveAdd(code, errorOrJson);

callback for archiveAdd

onArchiveShow(code, errorOrJson);

callback for archiveShow

onArchiveSummaryList(code, errorOrJson);

callback for archiveRequestSummaryList

onArchiveSelect(code, errorOrJson);

callback when user select archive

onArchiveThumbnail(code, errorOrJson, coverData, coverDataLen);

callback for archiveRequestThumbnail

onArchiveUpdate(code, errorOrJson);

callback for archiveUpdate

onArchiveLoad(code, errorOrJson, contentData, contentDataLen);

callback for archiveLoad

onArchiveRemove(code, errorOrJson);

callback for archiveRemove

onGamePlayerStats(code, errorOrJson);

callback for gamePlayerStatsRequest

onGameSummary(code, errorOrJson);

callback for gameSummaryRequest

onAdClose(code, errorOrJson);
onAdFail(code, errorOrJson);
onAdLeave(code, errorOrJson);
onAdOpen(code, errorOrJson);
onAdLoad(code, errorOrJson);
onAdClick(code, errorOrJson);
onAdImpression(code, errorOrJson);
onAdReward(code, errorOrJson);

手动集成

如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.

下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.

iOS 平台手动集成

Drag and drop the following frameworks from the plugins/ios folder of the HMS bundle into your Xcode project, check Copy items if needed when adding frameworks: 拖拽下列 framework 从 HMS 插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed

sdkbox.framework

PluginHMS.framework

上面的 frameworks 依赖于其他 frameworks。如果您没有添加它们,您也需要添加下列这些 frameworks:

SystemConfiguration.framework

plugin/jsbindings 文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes 文件夹中.

把刚刚拷贝的文件拖动到 Xcode 中或使用 File -> Add files to... 来添加.

Android 平台手动集成

拷贝文件

从插件安装包中的 plugin/android/libs 目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。

PluginHMS.jar

sdkbox.jar

plugin/android/jni 目录拷贝 pluginhms 以及 sdkbox 目录到您的工程的 proj.android/jni 目录。如果 sdkbox 目录在工程中已经存在,请覆盖它。

修改 build.gradle

你对 build.gradle 的修改可能会类似于下面的修改:

工程的根目录下的 build.gradle 修改


buildscript {
    repositories {
        google()
        jcenter()
        maven { url 'https://developer.huawei.com/repo/' } // for hms
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
        classpath 'com.huawei.agconnect:agcp:1.2.1.301' // for hms
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://developer.huawei.com/repo/' } // for hms
    }
}

应用级的 build.gradle 修改

apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect' // for hms

...

dependencies {
    ...
    implementation 'com.huawei.hms:base:4.0.4.301' // for hms
    implementation 'com.huawei.hms:hwid:4.0.4.300' // for hms
    implementation 'com.huawei.hms:iap:4.0.2.300' // for hms
    implementation 'com.huawei.hms:game:4.0.3.301' // for hms
}

编辑 AndroidManifest.xml

在标签 application tag 上添加下列权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.vending.BILLING"/>

编辑 Android.mk

编辑 proj.android/jni/Android.mk

LOCAL_STATIC_LIBRARIES 添加额外的库:

LOCAL_STATIC_LIBRARIES += PluginHMS
LOCAL_STATIC_LIBRARIES += sdkbox

在所有 import-module 语句之前添加一条 call 语句:

$(call import-add-path,$(LOCAL_PATH))

在最后添加额外的 import-module 语句:

$(call import-module, ./sdkbox)
$(call import-module, ./pluginhms)

这意味着您的语句顺序看起来像是这样:

$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginhms)

Note: 如果您使用的是 cocos2d-x 预编译库,那么保证这些语句在已有的 $(call import-module,./prebuilt-mk) 语句之上非常重要。

编辑 Application.mk (只限 Cocos2d-x v3.0 到 v3.2 版本)

编辑 proj.android/jni/Application.mk 保证 APP_STL 的定义正确。如果 Application.mk 包含了 APP_STL := c++_static 语句,那么这条语句应该被改为:

APP_STL := gnustl_static

plugin/jsbindings 文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes 文件夹中.

把你刚刚拷贝的 .cpp 文件添加到 Android.mk 文件的的 LOCAL_SRC_FILES 项.比如

LOCAL_SRC_FILES := hellocpp/main.cpp \
                  ../../Classes/AppDelegate.cpp \
                  ../../Classes/HelloWorldScene.cpp \
                                    ../../Classes/NewSourceFile.cpp

修改 AppActivity.java

插件版本 >= 2.4.0.3

  1. 找到 AppActivity.java 文件
find . -name "AppActivity.java"
  1. extends Cocos2dxActivity 替换为 extends com.sdkbox.plugin.SDKBoxActivity

以下是 AppActivity.java 不同版本的引擎所在的目录:

cpp
  - proj.android/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android/app/src/org/cocos2dx/cpp/AppActivity.java ( from cocos2d-x 3.17)

lua
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android-studio/app/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/lua/AppActivity.java (from cocos2d-x 3.17)

js
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/javascript/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/javascript/AppActivity.java ( from cocos2d-x 3.17)

插件版本 < 2.4.0.3

Note: 当你使用 cocos2d-x 源代码时,不同的版本中 Cocos2dxActivity.java 文件的位置也不同。一个确定该文件位置的方法是查看 proj.android/project.properties 。比如:

android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

在这个例子中, Cocos2dxActivity.java 文件应该在如下位置:

../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
onLoadNativeLibraries();
SDKBox.init(this);
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if(!SDKBox.onActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
          }
    }
    @Override
    protected void onStart() {
          super.onStart();
          SDKBox.onStart();
    }
    @Override
    protected void onStop() {
          super.onStop();
          SDKBox.onStop();
    }
    @Override
    protected void onResume() {
          super.onResume();
          SDKBox.onResume();
    }
    @Override
    protected void onPause() {
          super.onPause();
          SDKBox.onPause();
    }
    @Override
    public void onBackPressed() {
          if(!SDKBox.onBackPressed()) {
            super.onBackPressed();
          }
    }