游戏接入指南

接入前准备

开始接入前,请先向对接运营确认以下信息:

  • SDK 包和 Demo 工程
  • 渠道 ID、应用 ID、应用 Key
  • OnlySDK 服务端请求域名
  • 游戏服务端登录校验和支付回调地址

SDK下载

下载地址:http://wiki.begindcc.com/download/onlysdk/android/

引入jar包

onlysdk-core-*.jarandroid-support-multidex.jar 放到游戏接入工程的 libs 目录下。

修改only_developer_config.properties里面相关参数

从 Demo 工程复制配置文件到游戏接入工程的 assets 目录下,然后按实际渠道信息修改。


  具体位置:app/src/main
├── assets
│   ├── only_developer_config.properties
│   └── only_plugin_config.xml


需要在 only_developer_config.properties 中,根据实际接入信息修改以下参数:

  • ONLY_CHANNEL:渠道 ID
  • ONLY_APPID:游戏在该渠道的应用 ID
  • ONLY_APPKEY:游戏在该渠道的应用密钥
  • ONLY_SERVER_URL:请求域名地址(例如 https://xxx.xxx.com

以上参数请向对接运营确认后再填写。

配置Application

如果游戏没有自己的 Application,需要将 AndroidManifest.xml 中的 application 指定为 com.only.sdk.OnlyApplication

Application配置

如果游戏有自己的 Application,请参阅:自定义 Application

必须调用的接口

所有接口调用都通过 com.only.sdk.platform.OnlyPlatform 单例类完成。

1、初始化(必接)

该方法必须在游戏启动Activity的onCreate方法中调用

    OnlyPlatform.getInstance().init(this, new OnlyInitListener() {
        @Override
        public void onSwitchAccount(OToken data) {
            //游戏收到该回调,需要引导用户重新登录,重新加载该新用户对应的角色数据
            //参考 onLoginResult 回调,使用OToken参数进行登录验证
        }

        @Override
        public void onPayResult(int code, String msg) {
            Log.d("OnlySDK", "pay result. code:" + code + ";msg:" + msg);
            switch (code) {
                case OnlyCode.CODE_PAY_SUCCESS:
                    //"支付成功"
                    break;
                case OnlyCode.CODE_PAY_FAIL:
                    //"支付失败"
                    break;
                case OnlyCode.CODE_PAY_CANCEL:
                    //"支付取消"
                    break;
                case OnlyCode.CODE_PAY_UNKNOWN:
                    //"未知错误"
                    break;
            }
        }

        @Override
        public void onLogout() {
            //用户已经登出了
            //收到该回调需要返回游戏登录界面,并调用login接口,打开SDK登录界面
        }

        //游戏的服务端需要将以下相关参数发送到OnlySDK服务端进行登录校验
        //OToken中的参数如下:
        //userID:OnlyServer生成的唯一用户ID,游戏服务器需要将游戏账户ID和该userID进行绑定。
        //sdkUserID:渠道SDK平台用户唯一ID,一般不需要使用
        //username:OnlyServer生成的用户名,比如234234234.uc,4353453453.baidu,65756756756.360
        //sdkUserName:渠道SDK平台用户名,可能为空,部分渠道SDK没有返回用户名
        //token:OnlyServer生成的会话ID,游戏服务器拿该字段去OnlyServer做二次登录验证
        //extension:OnlyServer返回的扩展字段,部分渠道SDK需要,游戏中无需使用该字段的值
        //timestamp:OnlyServer生成的时间戳,游戏服务器去OnlyServer做二次登录验证时,传给OnlyServer

        @Override
        public void onLoginResult(int code, OToken data) {
            switch (code) {
                case OnlyCode.CODE_LOGIN_SUCCESS:
                    //进入游戏
                    //从OToken中获取用户信息
                    break;
                case OnlyCode.CODE_LOGIN_FAIL:
                    Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_LONG).show();
                    break;
            }
        }

        @Override
        public void onInitResult(int code, String msg) {
            Log.d("OnlySDK", "init result.code:" + code + ";msg:" + msg);
            if (code == OnlyCode.CODE_INIT_SUCCESS) {
                log("初始化成功" + code + " ...." + msg);
            } else {
                log("初始化失败..." + code);
            }
        }

        @Override
        public void onResult(int code, String msg) {
            if (code == OnlyCode.CODE_REAL_NAME_REG_SUC){
               //实名认证成功
               //该状态对应的msg内容:{"age": 18,"msg": "实名认证成功"}
            } else if (code == OnlyCode.CODE_REAL_NAME_REG_FAILED) {
              //实名认证失败
            }
        }
    });

2、登录接口(必接)

打开SDK登录界面,登录成功或者失败,会触发上面初始化监听器中的onLoginResult回调函数


    OnlyPlatform.getInstance().login(this);

3、登出接口(选接)

游戏方驱动SDK进行登出


    OnlyPlatform.getInstance().logout();

4、提交扩展数据(必接)

部分渠道要求在选择服务器,创建角色,登录游戏,角色升级,登出游戏等时刻,必须要上报游戏中玩家数据,以便渠道后台统计用户数据。所以,游戏层需要在特定的地方多次调用该方法。

    private void stat(final int dataType){
        StatData data = new StatData();
        data.setDataType(dataType);
        data.setMoneyNum(100);
        data.setRoleCreateTime(System.currentTimeMillis()/1000);
        data.setRoleID("role_100");
        data.setRoleName("test_112");
        data.setRoleLevel("10");
        data.setRoleLevelUpTime(System.currentTimeMillis()/1000);
        data.setServerID(10);
        data.setServerName("server_10");
        data.setTotalRechargeAmount("648.00");
        OnlyPlatform.getInstance().stat(data);
    }

该方法将调用的时机分为几种类型:

1:创建角色 2:进入游戏 3:等级提升 4:登出游戏 6:充值到账

所以在上面 5 个地方,都需要调用:

OnlyPlatform.getInstance().stat(StatData statData);

其中,StatData就是游戏内玩家的数据, 比如在创建角色时,statData中的dataType为1;(StatData.TYPE_CREATE_ROLE) 进入游戏时,dataType为2;(StatData.TYPE_ENTER_GAME) 等级提升时,dataType为3;(StatData.TYPE_LEVEL_UP) 登出游戏时,dataType为4;(StatData.TYPE_EXIT_GAME) 充值到账时,dataType为6;(StatData.TYPE_PAY_SUCCESSFUL)

关于StatData 数据结构:

参数名称参数类型参数说明
dataTypeint调用时机
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级
moneyNumString当前角色身上拥有的游戏币数量
roleCreateTimelong角色创建时间,从1970年到现在的时间,单位秒,必须传入真实的数据,否则UC审核不过
roleLevelUpTimelong角色等级变化时间,从1970年到现在的时间,单位秒
vipString玩家VIP等级
totalRechargeAmountString角色充值总金额(单位:元)

5、退出游戏(必接)

游戏方驱使SDK来关闭游戏. 通常的调用场景:玩家按下返回键时、玩家点击游戏内的“退出游戏”按钮.

    OnlyPlatform.getInstance().exitSDK(new OnlyExitListener() {
        @Override
        public void onGameExit() {
            //请在这个回调中,实现你自己的弹窗,询问玩家是否退出游戏(当渠道没有自己的退出弹框时,会使用该弹框)
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setTitle("退出确认");
            builder.setMessage("在 onGameExit 回调中,你需要实现你自己的弹窗,询问玩家是否退出游戏");
            builder.setCancelable(true);
            builder.setPositiveButton("继续游玩", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    //这里什么都不用做
                }
            });
            builder.setNeutralButton("关闭游戏", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    //退出游戏
                    MainActivity.this.finish();
                    System.exit(0);
                }
            });
            builder.show();
        }
    });

6、支付充值(必接)

调用充值接口,打开SDK充值界面。 充值成功或者失败,会触发上面初始化监听器中的onPayResult接口

        PayParams params = new PayParams();
        params.setOrderID("接入方订单id");
        params.setCoinNum(100);     //当前玩家身上拥有的游戏币数量
        params.setExtension(System.currentTimeMillis()+""); //游戏自定义数据,充值成功,回调游戏服的时候,会原封不动返回
        params.setPrice(100);         //单位 整数 分
        params.setRatio(10);            //兑换比率(比如1元等于10元宝填10,1元等于1元宝填1)
        params.setProductId("1");   //产品ID
        params.setProductName("元宝");    //产品名称
        params.setProductDesc("购买100元宝");   //产品描述
        params.setRoleId("1");      //角色ID
        params.setRoleLevel(1);     //角色等级
        params.setRoleName("测试角色名");    //角色名称
        params.setServerId("10");       //服务器ID
        params.setServerName("测试");     //服务器名称
        params.setVip("vip1");          //角色VIP等级
        params.setPayType(0);          //支付类型 默认为0:消耗性商品 1:订阅支付
        params.setPayNotifyUrl("https://game.example.com/pay/callback"); //支付成功,OnlyServer异步通知该地址,告诉游戏服务器发货

        OnlyPlatform.getInstance().pay(this, params);

关于PayParams对象:

参数名称参数类型参数说明
productIdString充值商品ID,游戏内的商品ID
productNameString商品名称,比如100元宝,500钻石...
productDescString商品描述,比如 充值100元宝,赠送20元宝
currencyString货币类型,比如CNY,ISO4217
priceint充值金额(单位:)
ratioint兑换比率(比如1元等于10元宝填10,1元等于1元宝填1)
coinNumint玩家当前身上剩余的游戏币
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级
vipString玩家vip等级
payTypeint支付类型 默认为0:消耗性商品 1:订阅支付
payNotifyUrlString游戏服务器支付回调地址,渠道SDK支付成功,异步通知OnlyServer,OnlyServer根据该地址,通知游戏服务器发货
extensionString支付成功之后,OnlyServer原样返回给游戏服务器

生命周期函数(必接)

在游戏启动Activity的如下生命周期函数中,调用对应的方法。

    @Override
    protected void onStart() {
        OnlySDK.getInstance().onStart();
        super.onStart();
    }

    @Override
    protected void onResume() {
        OnlySDK.getInstance().onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        OnlySDK.getInstance().onPause();
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        OnlySDK.getInstance().onStop();
    }

    @Override
    protected void onDestroy() {
        OnlySDK.getInstance().onDestroy();
        super.onDestroy();
    }


    @Override
    protected void onRestart() {
        OnlySDK.getInstance().onRestart();
        super.onRestart();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        OnlySDK.getInstance().onActivityResult(requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        OnlySDK.getInstance().onNewIntent(intent);
        super.onNewIntent(intent);
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        OnlySDK.getInstance().onConfigurationChanged(newConfig);
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        OnlySDK.getInstance().onRequestPermissionResult(requestCode, permissions, grantResults);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        OnlySDK.getInstance().onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        OnlySDK.getInstance().onRestoreInstanceState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }

打开客服聊天(选接)

调用客服聊天功能,需要传入角色以下信息

参数名称参数类型参数说明
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级
totalRechargeAmountString角色充值总金额(单位:元)

调用方法

    UserExtraData userExtraData = new UserExtraData();
    userExtraData.setServerID("1");
    userExtraData.setServerName("测试1服");
    userExtraData.setRoleID("123456");
    userExtraData.setRoleName("测试");
    userExtraData.setRoleLevel("5");
    userExtraData.setTotalRechargeAmount("648.00");
    OnlyPlatform.getInstance().openCustomerService(userExtraData);

打开问卷调查(选接)

调用问卷调查功能,需要以下信息

参数名称参数类型参数说明
formKeyString问卷表单Key(由运营提供)
extraString扩展参数
userExtraDataUserExtraData玩家角色信息

UserExtraData 角色信息

参数名称参数类型参数说明
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级

调用方法

    UserExtraData userExtraData = new UserExtraData();
    userExtraData.setServerID("1");
    userExtraData.setServerName("测试1服");
    userExtraData.setRoleID("123456");
    userExtraData.setRoleName("测试");
    userExtraData.setRoleLevel("5");
    OnlyPlatform.getInstance().openSurvey("问卷表单Key","", userExtraData);

推送通知开关(选接)

通知服务端,用户是否开启推送服务,需要以下信息

参数名称参数类型参数说明
consentStringtrue 允许推送 false 不允许推送
userExtraDataUserExtraData玩家角色信息

UserExtraData 角色信息

参数名称参数类型参数说明
serverIDString玩家所在服务器的ID
roleIDString玩家角色ID
roleNameString玩家角色名称

调用方法

   UserExtraData testdata = new UserExtraData();
                testdata.setServerID("1234");
                testdata.setRoleID("567");
                testdata.setRoleName("小明");
                OnlyPlatform.getInstance().canPush(true, testdata, new OnlyPushConsentListener() {
                    @Override
                    public void onConsentReported(ConsentResult response) {
                        android.util.Log.e("onlysdk","test push相关="+response);
                        if (response.code == 1) {
                            // 成功
                            android.util.Log.e("onlysdk","成功");
                        } else {
                            // 失败,result.msg 有详细信息
                        }
                    }
                });

获取用户可填写问卷列表(选接)

在游戏中,用户可能需要填写问卷以提供反馈或参与调查。此接口用于获取当前用户可填写的问卷列表,需要以下信息

参数名称参数类型参数说明
extraString扩展参数
userExtraDataUserExtraData玩家角色信息

UserExtraData 角色信息

参数名称参数类型参数说明
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级

响应格式为JSON,参数如下

参数类型描述
codeint状态码
msgString提示信息
dataList问卷表单列表
  • data数据结构
参数类型描述
appIdint游戏id
formKeyString问卷唯一标识(主要通过该参数控制显示
formUrlString问卷表单链接
formNameString问卷表单名称
formDescString问卷表单描述
expireTimelong问卷链接过期时间Unix时间戳
orderint问卷表单排序

调用方法

                UserExtraData userExtraData = new UserExtraData();
                userExtraData.setServerID("1");
                userExtraData.setServerName("测试1服");
                userExtraData.setRoleID("2199157473354");
                userExtraData.setRoleName("夏侯尔曼");
                userExtraData.setRoleLevel("5");
                OnlyPlatform.getInstance().getSurveyForms("", userExtraData, new OnlySurveyListener() {

                    @Override
                    public void onSurveyForms(String json) {
                        Log.e("OnlySdk", "json: " + json);
                    }
                });

获取企业微信-福利站信息(选接)

在游戏中,用户可能需要展示福利站信息。此接口用于获取平台配置的福利站信息,需要以下信息

参数名称参数类型参数说明
extraString扩展参数
userExtraDataUserExtraData玩家角色信息

UserExtraData 角色信息

参数名称参数类型参数说明
serverIDString玩家所在服务器的ID
serverNameString玩家所在服务器的名称
roleIDString玩家角色ID
roleNameString玩家角色名称
roleLevelString玩家角色等级

响应格式为JSON,参数如下

参数类型描述
codeint状态码
msgString提示信息
datajson福利站信息
  • 返回的json数据 data数据结构
参数类型描述
mpUrlString小程序跳转连接
qwPicUrlString添加企微图片
templatePicString模板图片

调用方法

                UserExtraData userExtraData = new UserExtraData();
                userExtraData.setServerID("1");
                userExtraData.setServerName("测试1服");
                userExtraData.setRoleID("2199157473354");
                userExtraData.setRoleName("夏侯尔曼");
                userExtraData.setRoleLevel("5");
                OnlyPlatform.getInstance().getWelfareInfo("", userExtraData, new OnlyRequestListener() {

                    @Override
                    public void onResponse(String result) {
                        Log.e("OnlySdk", "response: " + result);
                    }

                });

代金券上报数据(选接)

用于上报代金券支付数据,主要用于数据分析统计。

调用时机:需要上报代金券支付数据时

请求参数

参数类型必选描述
productNameString商品名称
productIdString商品ID
priceint价格(单位:分)
orderIDString订单ID
isPayedboolean是否已支付

调用示例

OnlyPlatform.getInstance().trackVoucher(
    "100元宝",           // 商品名称
    "com.game.coin100",  // 商品ID
    600,                  // 价格:6元(600分)
    "order_123456",      // 订单ID
    true                  // 是否已支付
);

自定义事件上报(选接)

用于上报自定义事件数据,支持灵活的事件属性配置。

调用时机:需要上报自定义事件时

请求参数

参数类型必选描述
eventNameString事件名称
propertiesJSONObject事件属性对象

调用示例

try {
    JSONObject properties = new JSONObject();
    properties.put("level", "10");
    properties.put("server_id", "1001");
    properties.put("item_type", "weapon");
    properties.put("item_name", "传说之剑");

    OnlyPlatform.getInstance().setTrackEvent("item_obtain", properties);
} catch (JSONException e) {
    e.printStackTrace();
}

具体上报事件需要跟运营沟通

激励视频广告(选接)

  • 调用时机:需要播放激励视频广告时
  • 请求参数:
参数类型必选描述
userIdString用户ID
posIdString广告ID
cpOrderIdString广告发货订单号
rewardNameString商品名称
rewardAmountString商品数量
serverIdString区服id
serverNameString区服信息
roleIdString角色ID
roleNameString角色名称
roleLevelString角色等级
extensionString扩展信息 没有传“无”
notifyUrlString游戏发货地址

调用方法

   AdvertiseEntity advertiseEntity = new AdvertiseEntity();
   advertiseEntity.setUserId("userId123");
   advertiseEntity.setPosId("1");
   advertiseEntity.setCpOrderId("111111");
   advertiseEntity.setRewardName("仙缘");
   advertiseEntity.setRewardAmount("60");
   advertiseEntity.setServerId("10");
   advertiseEntity.setServerName("黄鹤");
   advertiseEntity.setRoleId("roleId111");
   advertiseEntity.setRoleName("role123");
   advertiseEntity.setRoleLevel("1");
   advertiseEntity.setExtension("extension");
   advertiseEntity.setNotifyUrl("https://game.example.com/ad/callback");
   OnlyPlatform.getInstance().showVideoAd(advertiseEntity);

扫码授权PC登录(选接)

拉起摄像头,扫描PC端的登录二维码,授权PC登录

OnlyPlatform.getInstance().authByScanQrCode(new IComputer.Listener() {
            @Override
            public void callback(boolean isSuccessful, String msg) {
                if (isSuccessful){
//                    扫码授权成功
                }else {
//                    扫码授权失败
                }
            }
        });

获取用户商品订阅状态(选接)

获取用户维度的商品订阅状态,主要用于华为等渠道订阅支付状态查询,需要以下信息

参数类型描述
productIdString渠道订阅商品ID(如华为后台配置的商品ID,由我方运营提供)
OnlyPlatform.getInstance().getSubscriptionState("com.blrpj.hnhy.huawei.dy30", new OnlySubscriptionListener(){
    @Override
    public void onSuccess(int state) {
      // state=0,标识该订阅型商品为已购状态
    }
});
  • 返回值
参数类型描述
stateint订单交易状态。 -1:初始化 0:已购买 1:已取消 2:已退款 3:待处理

注意:

(选接)游戏重启,如游戏热更完成后需要重启,该方法会保存之前登录状态,用于静默登录

    OnlyPlatform.getInstance().hotReboot();

其它:

打开商店评分

    OnlyPlatform.getInstance().openStoreReview();

打开首页

    OnlyPlatform.getInstance().startHome(MainActivity.this);

打开分享,系统分享

    OnlyPlatform.getInstance().showShare(MainActivity.this);

获取商品本地化价格

    OnlyPlatform.getInstance().getPrice(MainActivity.this, hashMap -> {
        for (String key: hashMap.keySet()) {
            Log.i(TAG, "查询到商品ID:" + key + "的本地价格为" + hashMap.get(key));
        }
    });

切换SDK语言,每次启动调用一次

    OnlyPlatform.getInstance().switchLanguage(this, "zh-TW")

打开应用内评分功能

    OnlyPlatform.getInstance().showInAppReview(this);

打开Facebook首页

    OnlyPlatform.getInstance().showFacebookHome(this);

打开个人中心

    OnlyPlatform.getInstance().openCenter();

打开用户协议

    OnlyPlatform.getInstance().userAgreement();

打开隐私政策

    OnlyPlatform.getInstance().privacyPolicy();

打开官方微信公众号二维码/跳转企微

    OnlyPlatform.getInstance().officialAccount();