SDK接入和初始化
1 接入步骤
欢迎使用云游戏 SDK 。为方便 Android 开发者调试和接入海马云游戏多产品API,这里向您介绍适用于 Android 开发的工程配置。
1.1 SDK集成
将 SDK 库文件复制到工程的 libs 目录下;
在工程的 build.gradle 文件中,添加依赖属性:
repositories { flatDir { dirs 'libs' } } dependencies { implementation 'com.android.volley:volley:1.0.0' implementation 'com.alibaba:fastjson:1.2.0' implementation (name:'saas-sdk-release', ext: 'aar') }
注:
海马云游戏客户端 SDK 目前只支持通过 gradle 集成 SDK 方式
其中 saas-sdk-latest.release 是海马的 SDK,其他为海马 SDK 用到的包, saas-sdk-release 根据实际提供的 aar 文件进行修改(.aar文件的部分)。如果无法正常集成,请在Project的build.gradle文件中配置repositories,添加 jcenter
allprojects { repositories { jcenter() } }
1.2 配置渠道信息
渠道信息包括以下两个字段:
HMCP_ACCESS_KEY_ID:接入商的唯一ID,用来区分不同的接入商。该值由海马云分配,该value必须是String类型。
HMCP_CHANNEL_ID:渠道号,由接入商配置。如果应用本身不区分渠道,可以设置为一个随机的字符串。
这两个参数需要写在AndroidManifest.xml中,代码示例如下:
<application ……>
<meta-data android:name="HMCP_ACCESS_KEY_ID" android:value="海马商户分配的id" />
<meta-data android:name="HMCP_CHANNEL_ID" android:value="渠道id" />
……
</application>
1.3 参数配置
在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
请避免混淆海马SDK,在 Proguard 混淆文件中增加以下配置:
-dontwarn org.codehaus.** -keep class org.codehaus.** {*;} -keep interface com.haima.hmcp.listeners.*{*;} -keep class com.haima.hmcp.beans.*{*;} -keep enum com.haima.hmcp.enums.*{*;} -keep class com.haima.hmcp.**{*;} -keep enum com.haima.hmcp.websocket.WebSocketCloseNotification{*;} -keep interface com.haima.hmcp.websocket.WebSocket{*;} -keep interface com.haima.hmcp.websocket.WebSocketConnectionObserver{*;} -keep class com.haima.hmcp.websocket.WebSocketConnection{public <methods>;} -keep class com.haima.hmcp.websocket.WebSocketOptions{public <methods>;} -keep class com.haima.hmcp.websocket.WebSocketException{*;} -keep interface com.hmcp.saas.sdk.listeners.*{*;} -keep class com.hmcp.saas.sdk.beans.*{*;} -keep class com.hmcp.saas.sdk.enums.*{*;} -keep class com.hmcp.saas.sdk.SaasSDK{public <methods>;} -keep class de.tavendo.autobahn.**{*;} -keep class tv.haima.ijk.media.player.** { *; } -keep interface tv.haima.ijk.media.player.listeners.*{*;} -keep interface tv.haima.ijk.media.player.IMediaPlayer{*;} -keep class com.netease.LDNetDiagnoService.LDNetDiagnoService{public <methods>;} -keep interface com.netease.LDNetDiagnoService.LDNetDiagnoListener{public <methods>;} -keep class com.netease.LDNetDiagnoService.LDNetTraceRoute { *; } -dontwarn org.openudid.** -keep class org.openudid.**{*;}
1.4 添加组件
在布局文件中添加 HmcpVideoView 组件
<com.haima.hmcp.widgets.HmcpVideoView android:id="@+id/gameView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true"/>
HmcpVideoView 组件所在 Acitvity 需要设置以下属性:
<activity android:name=".xxxActivity" android:configChanges="orientation|screenSize" android:launchMode="singleTask" android:screenOrientation="landscape" />
1.5 Activity中初始化组件
以下是 Activity 中的示例代码,并且做了注释,后面还有详细的解释。
public class HmcpPlayerActivity extends AppCompatActivity implements HmcpPlayerListener {
private HmcpVideoView hmcpVideoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// 获取 HmcpVideoView 组件
hmcpVideoView = (HmcpVideoView) this.findViewById(R.id.gameView);
}
@Override
public void onError(ErrorType errorType, String s) {
// 出错信息回调
}
@Override
public void onSuccess() {
// SDK启动成功并且开始播流的回调
}
@Override
public void onMessage(Message message) {
// 收到退出登录消息回调
}
@Override
public void onPlayStatus(int status, long value, String data) {
// 帧率fps,带宽Bps上报。
}
@Override
public void onExitQueue() {
// 游戏内部弹窗退出消失回调
this.finish();
}
@Override
protected void onStart() {
hmcpVideoView.onStart();
super.onStart();
}
@Override
protected void onRestart() {
hmcpVideoView.onRestart(int time);
super.onRestart();
}
@Override
protected void onResume() {
hmcpVideoView.onResume();
super.onResume();
}
@Override
protected void onPause() {
hmcpVideoView.onPause();
super.onPause();
}
@Override
protected void onStop() {
hmcpVideoView.onStop();
super.onStop();
}
@Override
protected void onDestroy() {
if (hmcpVideoView != null) {
hmcpVideoView.onDestroy();
}
super.onDestroy();
}
@Override
public void onPlayerError(String errorCode, String errorMsg) {
//SDK上报错误信息回调接口
}
@Override
public void HmcpPlayerStatusCallback(String callback) {
//SDK使用状态回调接口
}
@Override
public void onSceneChanged(String sceneMessage) {
//SDK游戏过程中各状态发生变化时通知应用消息接口
}
@Override
public void onNetworkChanged(NetWorkState netWorkState) {
//网络变化后通知应用的接口
}
}
Activity 的 onResume()、onPause()、onDestroy() 必须重写,并在重写的方法中调用 HmcpVideoView 的相应方法,实现可以参考上面的示例代码。
Activity 需要 implements HmcpPlayerListener 接口
1.5.1 HmcpPlayerListener 接口说明
HmcpPlayerListener 监听类定义如下:
public interface HmcpPlayerListener {
/**
* 启动游戏失败
*
* @param errorType 错误的类型名:NETWORK_ERROR,OTHER
* @param errorInfo 错误的消息
*/
void onError(ErrorType type, String errorInfo);
/**
* 启动游戏成功
*/
void onSuccess();
/**
* 游戏退出
* 需要在该回调内调用 finish()时,退出 Activity
*/
void onExitQueue();
/**
* SDK内消息通知,包括支付消息等
*
* @param message 消息内容
*/
void onMessage(Message message);
/**
* SDK游戏过程中各状态发生变化时的回调
*
* @param sceneMessage 是JSON结构体,包含 sceneId 和 extraInfo{}
*/
void onSceneChanged(String sceneMessage);
/**
* 监听到网络变化后的通知
*
* @param state 是enum类型,包含 ISWIFI, NOTWIFI, NO_NETWORK
*/
void onNetworkChanged(NetWorkState state);
/**
* @param status:状态值,可为 0、1、2
* @param value:
* status=0,value是采样周期内接受到的视频帧的总大小,单位:Byte;
* status=1,value是采样周期内,渲染帧的总数;
* status=2,value是采样周期内,平均解码耗时,单位是ms;
*
* @param data:附加信息,status=0,data为采样周期内最大的N帧大小,单位为Byte;status=其他,data无数据;
*/
void onPlayStatus(int status, long value, String data);
/**
* 使用状态回调接口
*
* @param callback 状态信息
*/
void HmcpPlayerStatusCallback(String callback);
/**
* 上报错误信息回调接口
*
* @param errorCode 错误码
* @param errorMsg 错误信息
*/
void onPlayerError(String errorCode, String errorMsg);
/**
* 上报错误信息回调接口
*
* @param errorCode 错误码
* @param errorMsg 错误信息
*/
void onInputMessage(String message);
/**
* 监听到输入设备变化的通知
* TV端
* @param device 设备类型
* @param operationType 键盘类型
*/
void onInputDevice(int device, int operationType);
}
1.6 配置云游戏服务地址
String saasAuthUrl = "https://saas-rel.haimawan.com/s/rest/api";//saasAuth url地址
Bundle bundle = new Bundle();
bundle.putString(HmcpManager.BUNDLE_HMCP_SAAS_AUTH_URL, saasAuthUrl);
HmcpManager.getInstance().setServiceUrl(bundle);
2 快速入门
为方便 Android 开发者调试和接入海马云游戏产品 API,这里向您介绍适用于 Android 开发的快速接入文档。
重要接口 | 接口含义 | 建议调用时机 |
---|---|---|
init() | 初始化 SDK | Application 的 onCreate() |
setUserInfo() | 设置用户登录信息 | init() 成功回调后 |
generateCToken() | 计算 cToken 的值 | play(bundle) 调用前 |
play(bundle) | 与海马云 Server 建立通讯、申请服务,成功后则可以开启游戏 | init() 成功回调后 |
2.1 初始化SDK
若按照工程配置,已在 AndroidManifest.xml 文件中配置渠道信息:HMCP_ACCESS_KEY_ID 和 HMCP_CHANNEL_ID;
则直接调用 init 方法初始化,否则需进行 ACCESS_KEY_ID 与 CHANNEL_ID 通过Bundle赋值。
初始化方法建议在自定义 Application 类中进行,成功回调 success() 方法,则初始化成功;
函数原型
public class HmcpManager {
public void init(Context context, OnInitCallBackListener callBack)
public void init(Bundle bundle, Context context, OnInitCallBackListener callBack)
}
参数说明
参数 | 类型 | 说明 |
---|---|---|
mBID | String | 接入商的唯一 ID,用来区分不同的接入商,该值由海马云分配 |
mChannelID | String | 渠道号,由接入商配置。如果应用本身不区分渠道,可以设置为一个随机的字符串 |
bundle | Bundle | 使用协带 bundle 参数初始化 SDK ,渠道信息将使用 bundle 中携带信息, AndroidManifest.xml 中配置的信息将失效 |
context | Context | 应用程序上下文对象 |
callBack | OnInitCallBackListener | 初始化方法接口回调监听器 |
示例代码
HmcpManager manager = HmcpManager.getInstance();
// bundle.putString(HmcpManager.ACCESS_KEY_ID, mBid); // 设置ACCESS_KEY_ID
// bundle.putString(HmcpManager.CHANNEL_ID, mChannelID); // 设置CHANNEL_ID
// manager.init(bundle, this, new OnInitCallBackListener() { // 带bundle参数请调用该方法
manager.init(this, new OnInitCallBackListener() {
@Override
public void success() {
// 初始化SDK成功,可以云游戏
}
@Override
public void fail(String s) {
// 初始化SDK失败,不能云游戏
}
});
注:如使用 bundle 则 mBID、*mChannelID *都不能为空,如有空值则bundle信息失效,渠道信息将使用AndroidManifest.xml中配置的信息
2.2 设置用户登陆信息
用户登陆信息包括 userId 和 userToken,userId 作为游戏客户端用户的唯一识别码,在开始游戏前必须设置用户登陆信息并且需要保证唯一性。该值原则上为App端的用户登陆账号,登陆账号在用户注册时已经保证了唯一性。
如果没有用户登陆账号,可以随机生成长度在64以内的字符串,但需要每台客户端上的账号保证唯一性。
userToken 用来校验 userId 的有效性,如果 userId 为随机生成,userToken 也可以随机生成。
HmcpVideoView 的 setUserInfo() 用来设置用户的登陆信息。
函数原型
public class HmcpVideoView {
public void setUserInfo(UserInfo userInfo)
}
参数说明
参数 | 类型 | 说明 |
---|---|---|
userInfo | UserInfo | 用户登录信息 |
示例代码
mUserInfo = new UserInfo();
mUserInfo.userId = USER_ID;
mUserInfo.userToken = USER_TOKEN;
mUserInfo.userType = 0;
hmcpVideoView.setUserInfo(mUserInfo);
注:如果两台客户端上的 userId 相同,将会导致游戏异常现象。userType 代表用户类型,可以不传,默认 0 ,0 代表普通用户,5 代表超级账号,需要后台配合生效。
2.3 开始游戏
调用 HmcpVideoView的play(bundle)函数后,SDK会与海马云的server通讯,申请服务成功后可以开始游戏。
函数原型
public class HmcpVideoView {
public void play(Bundle bundle)
}
参数说明
参数 | 类型 | 必选 | 说明 |
---|---|---|---|
bundle | Bundle | 是 | 需调用对应put***()方法,将下列所有参数赋值并打包到bundle中 |
orientaion | ScreenOrientation | 是 | 标识游戏是竖屏显示还是横屏; 竖屏: ScreenOrientation.PORTRAIT 横屏: ScreenOrientation.LANDSCAPE |
playTime | Int | 是 | 用户可以玩游戏的时长,单位为毫秒/ms。 |
priority | Int | 是 | 用户申请游戏服务的优先级,默认写0。数值越大优先级越高。(逻辑暂未生效) |
packageName | String | 是 | 游戏包名,传入要启动的对应游戏包名 |
appChannel | String | 是 | 如果存在多款游戏同包名的情况,可以通过appChannel区分。如果不存在则可以忽略。 |
cToken | String | 是 | 用来校验参数的有效性,cToken的计算方法请参考服务端SDK文档 |
示例代码
boolean isPortraitOrientation = false; // 是否竖屏
ScreenOrientation orientaion = isPortraitOrientation ? ScreenOrientation.PORTRAIT : ScreenOrientation.LANDSCAPE;
int playTime = 6000 * 1000;
int priority = 100;
int appId = 123;
String packageNameGame = "com.yodo1tier1.skizgfTV.cmcc";
String appChannel = "";
String cToken = CryptoUtils.generateCToken(packageNameGame, userId, userToken, accessKeyID, channelID, accessKey);
// 传入参数
Bundle bundle = new Bundle();
bundle.putSerializable(HmcpVideoView.ORIENTATION, orientaion);
bundle.putInt(HmcpVideoView.PLAY_TIME, playTime);
bundle.putInt(HmcpVideoView.PRIORITY, priority);
bundle.putInt(HmcpVideoView.APP_ID, appId);
bundle.putString(HmcpVideoView.APP_NAME, packageName);
bundle.putString(HmcpVideoView.APP_CHANNEL, appChannel);
bundle.putString(HmcpVideoView.C_TOKEN, cToken);
// 开始游戏
hmcpVideoView.play(bundle);