HMS 集成指南
For the C++ 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
在您的工程中合适的地方初始化插件.我们推荐在 AppDelegate::applicationDidFinishLaunching()
or AppController:didFinishLaunchingWithOptions()
中.确保包含了相关的头文件:
#include "PluginHMS/PluginHMS.h"
AppDelegate::applicationDidFinishLaunching()
{
sdkbox::PluginHMS::init();
}
登录
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 的来支付.
const std::string productInfo = R"(
{
"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(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
sdkbox::PluginHMS::archiveAdd(playedTime, progress, description, supportCache,
bmBytes, bmBytesLen, bmBytesType,
dataBytes, dataBytesLen);
更新存档
将会触发 Listener 中的函数 onArchiveUpdate
sdkbox::PluginHMS::archiveUpdate(archiveId,
playedTime, progress, description,
bmBytes, bmBytesLen, bmBytesType,
dataBytes, dataBytesLen);
读存档
将会触发 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
的事件.
所有的回调中都包含一个 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::PluginHMSListener
:
#include "PluginHMS/PluginHMS.h"
class MyClass : public sdkbox::PluginHMSListener
{
private:
// Account
virtual void onLogin(int code, const std::string &msg) override;
// Player Info
virtual void onPlayerInfo(int code, const std::string& errorOrJson) override;
virtual void onPlayerExtraInfo(int code, const std::string& errorOrJson) override;
virtual void onPlayerGameBegin(int code, const std::string& errorOrJson) override;
virtual void onPlayerGameEnd(int code, const std::string& errorOrJson) override;
// IAP
virtual void onIAPReady(int code, const std::string& msg) override;
virtual void onIAPProducts(int code, const std::string& errorOrJson) override;
virtual void onIAPPurchase(int code, const std::string& errorOrJson) override;
virtual void onIAPPConsume(int code, const std::string& errorOrJson) override;
virtual void onIAPOwnedPurchases(int code, const std::string& errorOrJson) override;
virtual void onIAPOwnedPurchaseRecords(int code, const std::string& errorOrJson) override;
// Achievement
virtual void onAchievementList(int code, const std::string& errorOrJson) override;
virtual void onAchievementShow(int code, const std::string& errorOrJson) override;
virtual void onAchievementVisualize(int code, const std::string& errorOrJson) override;
virtual void onAchievementGrow(int code, const std::string& errorOrJson) override;
virtual void onAchievementMakeSteps(int code, const std::string& errorOrJson) override;
// Event
virtual void onEventList(int code, const std::string& errorOrJson) override;
// Ranking
virtual void onRankingSwitchStatus(int code, const std::string& errorOrJson) override;
virtual void onRankingSetSwitchStatus(int code, const std::string& errorOrJson) override;
virtual void onRankingSubmitScore(int code, const std::string& errorOrJson) override;
virtual void onRankingShow(int code, const std::string& errorOrJson) override;
virtual void onRankingList(int code, const std::string& errorOrJson) override;
virtual void onRankingCurPlayerScore(int code, const std::string& errorOrJson) override;
virtual void onRankingPlayerCenteredScores(int code, const std::string& errorOrJson) override;
virtual void onRankingMoreScores(int code, const std::string& errorOrJson) override;
virtual void onRankingTopScores(int code, const std::string& errorOrJson) override;
// Archive
virtual void onArchiveLimitThumbnailSize(int code, const std::string& errorOrJson) override;
virtual void onArchiveLimitDetailsSize(int code, const std::string& errorOrJson) override;
virtual void onArchiveAdd(int code, const std::string& errorOrJson) override;
virtual void onArchiveShow(int code, const std::string& errorOrJson) override;
virtual void onArchiveSummaryList(int code, const std::string& errorOrJson) override;
virtual void onArchiveSelect(int code, const std::string& errorOrJson) override;
virtual void onArchiveThumbnail(int code, const std::string& errorOrJson, unsigned char* coverData, unsigned int coverDataLen) override;
virtual void onArchiveUpdate(int code, const std::string& errorOrJson) override;
virtual void onArchiveLoad(int code, const std::string& errorOrJson, unsigned char* contentData, unsigned int contentDataLen) override;
virtual void onArchiveRemove(int code, const std::string& errorOrJson) override;
// Game Stats
virtual void onGamePlayerStats(int code, const std::string& errorOrJson) override;
virtual void onGameSummary(int code, const std::string& errorOrJson) override;
// Ad
virtual void onAdClose(int code, const std::string& errorOrJson) override;
virtual void onAdFail(int code, const std::string& errorOrJson) override;
virtual void onAdLeave(int code, const std::string& errorOrJson) override;
virtual void onAdOpen(int code, const std::string& errorOrJson) override;
virtual void onAdLoad(int code, const std::string& errorOrJson) override;
virtual void onAdClick(int code, const std::string& errorOrJson) override;
virtual void onAdImpression(int code, const std::string& errorOrJson) override;
virtual void onAdReward(int code, const std::string& errorOrJson) override;
}
- 创建一个监听类来接收回调事件:
sdkbox::PluginHMS::setListener(listener);
API Reference
Methods
static void setGDPR ( bool enabled ) ;
Set GDPR
static bool init ( ) ;
initialize the plugin instance.
static void setListener ( HMSListener * listener ) ;
Set listener to listen for adcolony events
static HMSListener * getListener ( ) ;
Get the listener
static void removeListener ( ) ;
Remove the listener, and can't listen to events anymore
static void login ( int loginType ) ;
HMS provider three way to login loginType: 0, slient login 1, login with HuaweiID(ID Token) 2, login with HuaweID(Authorization Code)
static void logout ( ) ;
logout HMS
static void playerRequestInfo ( ) ;
request current player info
static void playerRequestExtraInfo ( ) ;
request player extra info
static void playerSubmitGameBegin ( ) ;
submit game begin event
static void playerSubmitGameEnd ( ) ;
submit game end event
static void iapRequestProducts ( ) ;
static void iapPurchase ( const std::string & name ) ;
static void iapPurchaseWithPrice ( const std::string & productJson ) ;
static void iapRequestOwnedPurchases ( ) ;
static void iapConsume ( const std::string & purchaseToken ) ;
static void iapRequestOwnedPurchaseRecords ( ) ;
static void achievementRequestList ( ) ;
static void achievementShow ( ) ;
static void achievementVisualize ( const std::string & name ) ;
static void achievementGrow ( const std::string & achiveName , int steps ) ;
static void achievementMakeSteps ( const std::string & achiveName ,
int steps ) ;
static void achievementReach ( const std::string & achiveName ) ;
static void eventGrow ( const std::string & eventName , int amount ) ;
static void eventRequestList ( bool realtime ,
const std::string & eventNamas = "" ) ;
static void rankingRequestSwitchStatus ( ) ;
request if player allow open score in ranking
static void rankingSetSwitchStatus ( int status ) ;
request if player allow open score in ranking status: 0->player allow submit score, 1->player not allow submit score
static void rankingSubmitScore ( const std::string & rankingName ,
long score ,
const std::string unit = "" ) ;
submit score to ranking
static void rankingShow ( int timeDimension ,
const std::string & rankingName = "" ) ;
use hms's ui to show ranking
static void rankingRequestList ( bool realtime ,
const std::string & rankingName = "" ) ;
request ranking list
static void rankingRequestCurPlayerScore ( const std::string & rankingName ,
int timeDimension ) ;
request current player ranking score
static void rankingRequestPlayerCenteredScores ( const std::string & rankingName ,
int timeDimension ,
int size ,
bool realtime ) ;
request player centered scores
static void rankingRequestMoreScores ( const std::string & rankingName ,
int timeDimension ,
int offset ,
int pageSize ,
int pageDirection ) ;
request more scores
static void rankingRequestTopScores ( const std::string & rankingName ,
int timeDimension ,
int offset ,
int pageSize ,
int pageDirection ) ;
submit score to ranking
static void archiveRequestLimitThumbnailSize ( ) ;
get thumbnail max size
static void archiveRequestLimitDetailsSize ( ) ;
get detail max size
static void archiveAdd ( long playedTime ,
long progress ,
const std::string & description ,
bool supportCache ,
const unsigned char * bmBytes ,
int bmBytesLen ,
const std::string & bmBytesType ,
const unsigned char * dataBytes ,
int dataBytesLen ) ;
add archive
static void archiveShow ( const std::string & title ,
bool allowAdd ,
bool allowDelete ,
int pageSize ) ;
use hms's default ui to show archive
static void archiveRequestSummaryList ( bool realtime ) ;
request archive summay list, developer can show custome archive list with the returned data
static void archiveRequestThumbnail ( const std::string & archiveId ) ;
request archive cover thumbnail
static void archiveUpdate ( const std::string & archiveId ,
long playedTime ,
long progress ,
const std::string & description ,
const unsigned char * bmBytes ,
int bmBytesLen ,
const std::string & bmBytesType ,
const unsigned char * dataBytes ,
int dataBytesLen ) ;
update archive
static void archiveLoad ( const std::string & archiveId , int conflictPolicy ) ;
load archive
static void archiveRemove ( const std::string & archiveId ) ;
remvoe archive
static void gamePlayerStatsRequest ( bool realtime ) ;
request game player statistics
static void gameSummaryRequest ( bool realtime ) ;
request game summary
static void buoyShow ( ) ;
static void buoyHide ( ) ;
static void adCache ( const std::string & name ) ;
static void adShow ( const std::string & name ) ;
static void adHide ( const std::string & name ) ;
static bool adIsAvailable ( const std::string & name ) ;
static void adSetRewardData ( const std::string & custom_data ) ;
static void adSetRewardUserId ( const std::string & user_id ) ;
static void adSetAdContentClassification ( const std::string & adContentClassification ) ;
static void adSetTagForUnderAgeOfPromise ( int tagForUnderAgeOfPromise ) ;
static void adSetTagForChildProtection ( int tagForChildProtection ) ;
static void adSetNonPersonalizedAd ( int nonPersonalizedAd ) ;
Listeners
void onLogin ( int code , const std::string & errorOrJson );
void onPlayerInfo ( int code , const std::string & errorOrJson ) {
void onPlayerExtraInfo ( int code , const std::string & errorOrJson ) {
void onPlayerGameBegin ( int code , const std::string & errorOrJson ) {
void onPlayerGameEnd ( int code , const std::string & errorOrJson ) {
void onIAPReady ( int code , const std::string & errorOrJson ) {
void onIAPProducts ( int code , const std::string & errorOrJson ) {
void onIAPPurchase ( int code , const std::string & errorOrJson ) {
void onIAPConsume ( int code , const std::string & errorOrJson ) {
void onIAPOwnedPurchases ( int code , const std::string & errorOrJson ) {
void onIAPOwnedPurchaseRecords ( int code , const std::string & errorOrJson ) {
void onAchievementList ( int code , const std::string & errorOrJson ) {
void onAchievementShow ( int code , const std::string & errorOrJson ) {
void onAchievementVisualize ( int code , const std::string & errorOrJson ) {
void onAchievementGrow ( int code , const std::string & errorOrJson ) {
void onAchievementMakeSteps ( int code , const std::string & errorOrJson ) {
void onEventList ( int code , const std::string & errorOrJson ) {
void onRankingSwitchStatus ( int code , const std::string & errorOrJson ) {
void onRankingSetSwitchStatus ( int code , const std::string & errorOrJson ) {
void onRankingSubmitScore ( int code , const std::string & errorOrJson ) {
callback for rankingSubmitScore
void onRankingShow ( int code , const std::string & errorOrJson ) {
callback for rankingShow
void onRankingList ( int code , const std::string & errorOrJson ) {
callback for rankingRequestList
void onRankingCurPlayerScore ( int code , const std::string & errorOrJson ) {
callback for rankingRequestCurPlayerScore
void onRankingPlayerCenteredScores ( int code ,
const std::string & errorOrJson ) {
callback for rankingRequestPlayerCenteredScores
void onRankingMoreScores ( int code , const std::string & errorOrJson ) {
callback for rankingRequestMoreScores
void onRankingTopScores ( int code , const std::string & errorOrJson ) {
callback for rankingRequestTopScores
void onArchiveLimitThumbnailSize ( int code ,
const std::string & errorOrJson ) {
callback for archiveRequestLimitThumbnailSize
void onArchiveLimitDetailsSize ( int code , const std::string & errorOrJson ) {
callback for archiveRequestLimitDetailsSize
void onArchiveAdd ( int code , const std::string & errorOrJson ) {
callback for archiveAdd
void onArchiveShow ( int code , const std::string & errorOrJson ) {
callback for archiveShow
void onArchiveSummaryList ( int code , const std::string & errorOrJson ) {
callback for archiveRequestSummaryList
void onArchiveSelect ( int code , const std::string & errorOrJson ) {
callback when user select archive
void onArchiveThumbnail ( int code ,
const std::string & errorOrJson ,
unsigned char * coverData ,
unsigned int coverDataLen ) {
callback for archiveRequestThumbnail
void onArchiveUpdate ( int code , const std::string & errorOrJson ) {
callback for archiveUpdate
void onArchiveLoad ( int code ,
const std::string & errorOrJson ,
unsigned char * contentData ,
unsigned int contentDataLen ) {
callback for archiveLoad
void onArchiveRemove ( int code , const std::string & errorOrJson ) {
callback for archiveRemove
void onGamePlayerStats ( int code , const std::string & errorOrJson ) {
callback for gamePlayerStatsRequest
void onGameSummary ( int code , const std::string & errorOrJson ) {
callback for gameSummaryRequest
void onAdClose ( int code , const std::string & errorOrJson ) {
void onAdFail ( int code , const std::string & errorOrJson ) {
void onAdLeave ( int code , const std::string & errorOrJson ) {
void onAdOpen ( int code , const std::string & errorOrJson ) {
void onAdLoad ( int code , const std::string & errorOrJson ) {
void onAdClick ( int code , const std::string & errorOrJson ) {
void onAdImpression ( int code , const std::string & errorOrJson ) {
void onAdReward ( int code , const std::string & 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
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
修改 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();
}
}