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.plist
的 LSApplicationQueriesSchemes
下添加名单。
关于 Creator 工程
Creator 导出工程会修改工程的配置, 这可能会影响 SDKBox 对工程的配置修改. 所以可以有以下做法(任选其一):
- 保存导出工程中的修改, 对于 SDKBox 来说可能有这些文件(mk, gradle, gradle.properties, AppDelegate.cpp, ...), 导出后再恢复对应该文件
- 在每一次 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 测试
- HMS 不支持 iOS 平台, 在 iOS 其实是一个空的实现
Android 测试
- 在 AppGallery 中创建一个 app
- 启起你想要使用的模块(比如你要使用登录, 就可以启用AccountKit)
- 添加app的签名hash
- 下载应用的信息文件
agconnect-services.json
HMS 的官方文档
使用
初始化 HMS
- 在您的代码合适的地方调用
init()
完成初始化. 我们推荐在app.js
中完成初始化.比如:
sdkbox.PluginHMS.init();
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
包含如下头文件:
#include "PluginHMSJS.hpp"
#include "PluginHMSJSHelper.h"
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
确保调用了如下函数:
sc->addRegisterCallback(register_all_PluginHMSJS);
sc->addRegisterCallback(register_all_PluginHMSJS_helper);
登录
HMS 提供了三种登录方式:
- Signing In with HUAWEI ID(ID Token)
sdkbox.PluginHMS.login(1);
- Signing In with HUAWEI ID(Authorization Code)
sdkbox.PluginHMS.login(2);
- Silently Signing In With HUAWEI ID
静默登录只能在上一次使用前两种方式已经登录成功的情况下,才能在静态登录下成功
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 :
- https://developer.huawei.com/consumer/cn/doc/development/HMS-References/game-return-code-v4
- https://developer.huawei.com/consumer/cn/doc/development/HMS-References/hms-error-code
这里单独列出常见的一些值的含义:
- 7020: 本地cache中没有数据
- 7022: 未实名或未成年人
- 7024: 手机中没有安装 "华为应用市场"
- 7218: 华为应用市场中的游戏服务未打开,或用户取消
- 7204: 需要安装应用助手最新版
- 7013: 未登录帐号 或 在调用 Archive 相关接口时报这个错,也可能是 sdkbox_config 中的 archive 未设置为 true
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
-
如果你使用 cocos2d-x 源码,拷贝 jar 文件到:
Android command-line:
cocos2d/cocos/platform/android/java/libs
Android Studio:
cocos2d/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-js 或者 lua ,拷贝 jar 文件到:
Android command-line:
frameworks/cocos2d-x/cocos/platform/android/java/libs
Android Studio:
frameworks/cocos2d-x/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-x 预编译包,拷贝 jar 文件到:
Android command-line:
proj.android/libs
从 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
- 找到 AppActivity.java 文件
find . -name "AppActivity.java"
- 把
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
-
如果您使用 cocos2d-x 源代码,假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/ lib/Cocos2dxActivity.java
-
如果您使用 cocos2dx-x 预编译库, 假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:./src/org/cocos2dx/lib/Cocos2dxActivity.java
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
- 修改
Cocos2dxActivity.java
文件,导入如下包:
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
- 然后,修改
Cocos2dxActivity
类的onCreate(final Bundle savedInstanceState)
函数,添加一个调用语句SDKBox.init(this);
。添加的位置非常重要,必须在调用onLoadNativeLibraries();
之后。如下:
onLoadNativeLibraries();
SDKBox.init(this);
-
最后, 我需要提供合适的 overrides 方法的代码。这里有一些约定如下。
-
如果这个被列出的方法没有在
SDKBox
中定义,那么__定义它__。 -
如果这个被列出的方法已经被定义在
SDKBox
中,那么请调用这个在SDKBox
中的__同名方法__。
-
@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();
}
}