更新日期:2024-08-01Java(Android)接入文档
根据游戏接入后出现的问题,QuickSDK对游戏项目做以下几点要求:
· AndroidManifest.xml中android:targetSdkVersion="26" (关于一些应用市场对Android应用API(targetSdkVersion)最低要求的提示)
部分渠道targetVersion为28时9.0设备http请求失败
application节点下添加
android:usesCleartextTraffic="true"
防止游戏与渠道sdk发生横竖屏切换出现问题
· U3D游戏项目下,AndroidManifest.xml中
Android:value值设置为true
· 为Activity添加横竖屏设置
根据游戏的横竖屏,将activity做横竖屏设置
android:screenOrientation="sensorLandscape" android:screenOrientation="sensorPortrait"
或者
android:screenOrientation="landscape" android:screenOrientation="portrait"
· AndroidManifest.xml中的Activity等组件路径为完整路径
· 游戏项目的类路径不要使用“com.quicksdk”,打渠道包时会删除该路径下的所有内容。
去下载中心下载QuickSDK资源,将files文件夹下的文件libs和res拷贝到项目对应的文件夹中。
Androidmanifest.xml中添加权限(QuickSDK没有要求任何权限,游戏按自己的需要进行添加便可)
2.3.1 新建游戏的Application(必接)
新建游戏的Application,继承自QuickSdkApplication
public class GameApplication extends QuickSdkApplication { @Override public void onCreate() { super.onCreate(); } }
2.3.2 将Application添加到AndroidManifest.xml中(必接)
在AndroidManifest.xml中的Application节点,修改android:name属性,其值为游戏新建的Application的全路径
2.4.1 新建游戏闪屏Activity(必接)
新建游戏闪屏Activity,继承自QuickSdkSplashActivity
public class SplashActivity extends QuickSdkSplashActivity { @Override public int getBackgroundColor() { return Color.WHITE; } @Override public void onSplashStop() { //闪屏结束后,跳转到游戏界面 Intent intent = new Intent(this, MainActivity.class); startActivity(intent); this.finish(); } }
2.4.2 将闪屏Activity添加到AndroidManifest.xml中,并且设置为游戏启动Activity
说明:
android:name属性,其值为游戏自定义的闪屏Activity全路径
android:screenOrientation属性,其值根据游戏需求决定是横屏还是竖屏
2.4.3 高TargetSdkVesion强更适配(不使用强更可跳过此步骤)
备注: android:grantUriPermissions="true">的U注意大写!!!
2.4.4 在res下新建一个xml文件夹,在文件夹内新建一个filepaths.xml,并复制一下内容(不使用强更可跳过此步骤)
游戏Activity的生命周期,调用相应的方法
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); com.quicksdk.Sdk.getInstance().onCreate(this); } @Override protected void onStart() { super.onStart(); com.quicksdk.Sdk.getInstance().onStart(this); } @Override protected void onRestart() { super.onRestart(); com.quicksdk.Sdk.getInstance().onRestart(this); } @Override protected void onPause() { super.onPause(); com.quicksdk.Sdk.getInstance().onPause(this); } @Override protected void onResume() { super.onResume(); com.quicksdk.Sdk.getInstance().onResume(this); } @Override protected void onStop() { super.onStop(); com.quicksdk.Sdk.getInstance().onStop(this); } @Override protected void onDestroy() { super.onDestroy(); com.quicksdk.Sdk.getInstance().onDestroy(this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); com.quicksdk.Sdk.getInstance().onNewIntent(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); com.quicksdk.Sdk.getInstance().onActivityResult(this, requestCode, resultCode, data); }
2.6.1 设置初始化通知(必接)
类名:QuickSDK
方法:public QuickSDK setInitNotifier(InitNotifier notifier)
功能:设置初始化结果回调通知,一般在游戏开始前,初始化成功后,进行游戏登陆等相关的处理。
案例:
QuickSDK.getInstance().setInitNotifier(new InitNotifier() { @Override public void onSuccess() { //初始化成功 } @Override public void onFailed(String message, String trace) { //初始化失败 } });
2.6.2 设置登录通知(必接)
类名:QuickSDK
方法:public QuickSDK setLoginNotifier(LoginNotifier notifier)
功能:设置用户登陆结果回调通知的相关处理。
案例:
QuickSDK.getInstance().setLoginNotifier(new LoginNotifier() { @Override public void onSuccess(UserInfo userInfo) { //登录成功,获取到用户信息userInfo //通过userInfo中的UID、token做服务器登录认证 } @Override public void onCancel() { //登录取消 } @Override public void onFailed(final String message, String trace) { //登录失败 } });
登录信息:
UserInfo
字段
类型
说明
UID
String
用户ID,SDK返回的唯一ID
username
String
用户登录名
token
String
用户验证token
接入要求:
1)启动游戏,在登录界面中获取到登录成功的通知,跳转到进入游戏的界面;
2)游戏以自动登录的方式调用登录时,获取到登录失败和登录取消的通知,应再次调用登录的功能;
3)不同渠道可能返回相同的UID,游戏应使用渠道ID+UID作为用户的唯一标识。渠道ID通过“public int getChannelType()”获取。
2.6.3 设置注销通知(必接)
类名:QuickSDK
方法:public QuickSDK setLogoutNotifier(LogoutNotifier notifier)
功能:设置用户注销结果回调通知等相关的处理。
案例:
QuickSDK.getInstance().setLogoutNotifier(new LogoutNotifier() { @Override public void onSuccess() { //注销成功 } @Override public void onFailed(String message, String trace) { //注销失败,不做处理 } });
接入要求: 获取到注销成功的通知,游戏应回到登录界面并重新调用登录方法。
2.6.4 设置切换账号通知(必接)
类名:QuickSDK
方法:public QuickSDK setSwitchAccountNotifier(SwitchAccountNotifier notifier)
功能: 一些渠道(如:百度 等)在悬浮框有切换账号的功能,此回调即切换成功后的回调。游戏应清除当前的游戏角色信息。在切换账号成功后回到选择服务器界面,用回调结果里面的新的UID 和Token 进入游戏。注意:在此回调内无需调用登录接口
案例:
QuickSDK.getInstance().setSwitchAccountNotifier(new SwitchAccountNotifier() { @Override public void onSuccess(UserInfo userInfo) { //切换账号成功的回调,返回新账号的userInfo } @Override public void onCancel() { //切换账号取消 } @Override public void onFailed(String message, String trace) { //切换账号失败 } })
切换账号成功信息:
UserInfo
字段
类型
说明
UID
String
用户ID,SDK返回的唯一ID
username
String
用户登录名
token
String
用户验证token
接入要求:
在游戏界面中,获取到切换账号成功的通知,游戏注销当前的游戏角色,使用新的用户信息,回到进入游戏的界面。(针对渠道SDK在游戏界面中通过悬浮框进行账号的切换)
2.6.5 设置定额支付通知(必接)
类名:QuickSDK
方法:public QuickSDK setPayNotifier(PayNotifier notifier)
功能:设置用户支付结果回调通知等相关的处理
案例:
QuickSDK.getInstance().setPayNotifier(new PayNotifier() { @Override public void onSuccess(String sdkOrderID, String cpOrderID, String extrasParams) { //支付成功 //sdkOrderID:quick订单号 cpOrderID:游戏订单号 } @Override public void onCancel(String cpOrderID) { //支付取消 } @Override public void onFailed(String cpOrderID, String message, String trace) { //支付失败 } });
说明:游戏充值是否成功到账,只能以服务器的通知为准,而不是客户端的通知,因为部分渠道SDK自身有时不会发送正确的通知。
2.6.6 设置退出通知(必接)
类名:QuickSDK
方法:public QuickSDK setExitNotifier(ExitNotifier notifier)
功能:设置用户退出结果回调通知等相关的处理
案例:
QuickSDK.getInstance().setExitNotifier(new ExitNotifier() { @Override public void onSuccess() { //退出成功,游戏在此做自身的退出逻辑处理 } @Override public void onFailed(String message, String trace) { //退出失败,不做处理 } });
接入要求:获取到退出成功的通知后,游戏做自身的退出逻辑处理。
接入要求:SDK的接口需在UI主线程下调用
2.7.1 SDK初始化(必接)
类名:com.quicksdk.Sdk
方法:public void init(Activity activity, String productCode, String productKey)
功能:渠道SDK初始化
参数:activity 必填 当前Activity
targetVersion大于等于23时,需要在初始化之前申请权限(QuickSDK没有要求任何权限,游戏按自己的需要进行申请便可,如不用可以不做申请)如下:
案例1(当targetVersion 较大时 动态申请读写权限和读取手机状态等权限,具体权限 具体而定):
try { //check权限 if ((ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) || (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) { //没有,申请权限 权限数组 ActivityCompat.requestPermissions(MainActivity.this, new String[] { Manifest.permission.READ_PHONE_STATE ,Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUESTCODE); } else { // 有则执行初始化 Sdk.getInstance().init(this, "Product_Code", "Product_Key"); } } catch (Exception e) { //异常 继续申请 ActivityCompat.requestPermissions(MainActivity.this, new String[] { Manifest.permission.READ_PHONE_STATE ,Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUESTCODE); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //如果requestCode不是游戏自己申请时传的,则不作处理 if (requestCode != REQUESTCODE){ return; } if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //申请成功 Sdk.getInstance().init(this,"Product_Code", "Product_Key"); } else { //失败 这里逻辑以游戏为准 这里只是模拟申请失败 cp方可改为继续正常初始化调登录然后进游戏 或者继续申请权限 或者退出游戏 或者其他逻辑 Sdk.getInstance().init(this,"Product_Code", "Product_Key"); } }
targetVersion小于等于22时,无申请权限。如下:
案例2:
QuickSDK.getInstance().setInitNotifier(new InitNotifier() { @Override public void onSuccess() { //初始化成功 } @Override public void onFailed(String message, String trace) { //初始化失败 } });
productCode 必填 QuickSDK后台申请的productCode
productKey 必填 QuickSDK后台申请的productKey
案例:
com.quicksdk.Sdk.getInstance().init(activity, "后台申请的productCode", "后台申请的productKey");
接入要求:初始化接口,应在Activity中onCreate方法中调用。
2.7.2 登录账号(必接)
类名:com.quicksdk.User
方法:public void login(Activity activity)
功能:调用渠道SDK登录
参数:activity 必填 当前Activity
案例:
User.getInstance().login(activity);
接入要求:进入到登录界面,自动调用此接口,须保证初始化成功后再调用登录接口。
2.7.3 上传角色信息(必接)
类名:com.quicksdk.User
方法:public void setGameRoleInfo(Activity activity, GameRoleInfo roleInfo, boolean createRole)
功能:向渠道SDK上传角色信息
参数:activity 必填 当前Activity
roleInfo 必填 角色信息
createRole 必填 是否创建角色
案例:
//注:GameRoleInfo的字段,以下所有参数必须传,没有的请模拟一个参数传入; GameRoleInfo roleInfo = new GameRoleInfo(); roleInfo.setServerID("1");//数字字符串,不能含有中文字符 roleInfo.setServerName("服务器1"); roleInfo.setGameRoleName("石头"); roleInfo.setGameRoleID("1121121"); roleInfo.setGameBalance("5000"); roleInfo.setVipLevel("4"); //设置当前用户vip等级,必须为数字整型字符串,请勿传"vip1"等类似字符串 roleInfo.setGameUserLevel("12"); //设置游戏角色等级 roleInfo.setPartyName("无敌联盟"); //设置帮派名称 roleInfo.setRoleCreateTime("1473141432"); //值为10位数时间戳 roleInfo.setPartyId("1100"); //设置帮派id,必须为整型字符串 roleInfo.setGameRoleGender("男"); roleInfo.setGameRolePower("38"); //设置角色战力,必须为整型字符串 roleInfo.setPartyRoleId("11"); //设置角色在帮派中的id roleInfo.setPartyRoleName("帮主"); //设置角色在帮派中的名称 roleInfo.setProfessionId("38"); //设置角色职业id,必须为整型字符串 roleInfo.setProfession("法师"); //设置角色职业名称 roleInfo.setFriendlist("无"); //设置好友关系列表,格式请参考:http://open.quicksdk.net/help/detail/aid/190 创建角色 User.getInstance().setGameRoleInfo(activity, roleInfo, true); 进入游戏及角色升级 User.getInstance().setGameRoleInfo(activity, roleInfo, false);
GameRoleInfo
字段
类型
说明
serverID
String
服务器ID(数字字符串)
serverName
String
服务器名称
gameRoleName
String
角色名称
gameRoleID
String
角色ID
gameRoleBalance
String
角色用户余额
vipLevel
String
VIP等级
gameRoleLevel
String
角色用户等级
partyName
String
公会社团
roleCreateTime
String
角色创建时间(10位数的unix timestamp时间戳)
partyId
String
帮派id
gameRoleGender
String
角色性别
gameRolePower
String
战力
partyRoleId
String
角色在帮派中的id
partyRoleName
String
角色在帮派中的名称
professionId
String
角色职业id
profession
String
角色职业名称
friendlist
String
好友关系列表
接入说明:
1) 在创建游戏角色、进入游戏和角色升级3个地方调用此接口,当创建角色时createRole值为true,其他两种情况为false。true & false 均需要调用一遍
2) GameRoleInfo所有字段均需上传,不能传null,游戏没有的字段可以传一个默认值(比如 default 或者 1 之类的)。
3) 关于360渠道上传角色信息的具体说明,请参考:https://www.quicksdk.com/doc-190.html?cid=15
2.7.4 定额支付(必接)
类名:com.quicksdk.Payment
方法:public void pay(final Activity activity, final OrderInfo orderInfo, final GameRoleInfo roleInfo)
功能:调用渠道SDK支付
参数:activity 必填 当前Activity
orderInfo 所有参数必填 订单信息
roleInfo 所有参数必填 角色信息
案例:
GameRoleInfo roleInfo = new GameRoleInfo(); roleInfo.setServerID("1");//数字字符串 roleInfo.setServerName("服务器1"); roleInfo.setGameRoleName("石头"); roleInfo.setGameRoleID("1121121"); roleInfo.setRoleCreateTime("1473141432"); //值为10位数时间戳 roleInfo.setGameUserLevel("12"); roleInfo.setVipLevel("4"); roleInfo.setGameBalance("5000"); roleInfo.setPartyName("xx联盟"); OrderInfo orderInfo = new OrderInfo(); orderInfo.setCpOrderID("20150917003200119310"); orderInfo.setGoodsName("元宝");//商品名称,不带数量 orderInfo.setCount(60);//游戏币数量 orderInfo.setAmount(6); orderInfo.setGoodsID("1"); orderInfo.setGoodsDesc("Diamond_60_商品描述"); orderInfo.setPrice(0.1); orderInfo.setExtrasParams("额外参数"); Payment.getInstance().pay(activity, orderInfo, roleInfo);
支付信息参数表:
OrderInfo
字段
类型
说明
goodsID
String
产品ID,用来识别购买的产品
goodsName
String
产品名称
cpOrderID
String
产品订单号(游戏方的订单号)
count
int
游戏币数量
amount
double
总金额(元)
price
double
总金额(元,跟amount传一样的值就行)
String
商品描述
extrasParams
String
透传参数 服务器发送异步通知时原样回传(需要传纯字符串,不能传json格式)
为了兼容各个渠道商品名称能够统一显示,订单应以如下案例的形式传入:
案例1: 案例2:
amount:6.0 amount:10.0
count:60 count:1
goodsName:元宝 goodsName:月卡
接入要求:
· GoodsName产品名称以“月卡”、“钻石”、“元宝”的形式传入,不带数量;
· 其中OrderInfo中Count字段表示游戏币数量
· OrderInfo,GameRoleInfo所有字段均需上传且不能传null,游戏没有的字段可以传一个默认值(比如 default 或者 1 之类的)
2.7.5 注销账号(游戏自身需要登出SDK账号时进行调用)
类名:com.quicksdk.User
方法:public void logout(Activity activity)
功能:渠道SDK注销
案例:
User.getInstance().logout(activity);
2.7.6 退出(必接)
类名:com.quicksdk.Sdk
方法:public void exit(Activity activity)
功能:渠道SDK退出,游戏做退出逻辑时,先通过isShowExitDialog接口判断渠道是否有退出框,如果渠道有退出框,直接调用QuickSDK的exit接口;如果渠道没有退出框,则调用游戏自身的退出框,退出框点击“确定”后,调用QuickSDK的exit接口。
案例:
//通过isShowExitDialog判断渠道sdk是否有退出框 if(QuickSDK.getInstance().isShowExitDialog()){ Sdk.getInstance().exit(activity); }else{ // 游戏调用自身的退出对话框,点击确定后,调用quick的exit接口 new AlertDialog.Builder(MainActivity.this).setTitle("退出").setMessage("是否退出游戏?").setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { Sdk.getInstance().exit(MainActivity.this); } }).setNegativeButton("取消", null).show(); }
类名:com.quicksdk.Extend
方法:public int getChannelType()/getParentChannelType()
功能:获取复制渠道的父渠道号/获取渠道号
说明:渠道ID
案例:
Extend.getInstance().getParentChannelType();//获取复制渠道的父渠道号 Extend.getInstance().getChannelType();//获取渠道号
比如渠道code:25643,渠道名:官方自用渠道 是从渠道code:134,渠道名:QuickGame_安卓 渠道复制而来,那么通过getParentChannelType接口获取到的值就是134,通过getChannelType接口获取到的就是25643。为了父渠道跟复制渠道的包能角色互通,推荐游戏使用getParentChannelType接口直接获取父渠道code做uid拼接
类名:com.quicksdk.Extend
方法:public String getDeviceID(Activity activity)
功能:获取QuickSDK定义的设备号
说明:此设备号仅以QuickSDK算法计算得来,与渠道或cp设备号不一致;
案例:
Extend.getInstance().getDeviceID(MainActivity.this);
方法:public void uploadNode(Activity activity,String eventCode ,String eventParams)
功能:上传cp自定义的数据
说明:上传cp自定义的数据
案例:
Extend.getInstance(). uploadNode(activity,"eventCode ","eventParams");
类名:com.quicksdk.Extend
方法:public String getExtrasConfig(String key)
功能:获取配置参数值
说明:运行游戏自定义参数配置在quicksdk.xml文件中,根据一定的规则,在打包的时候进行改变
案例:
Extend.getInstance().getExtrasConfig("key");
类名:com.quicksdk.Extend
方法:public boolean isFunctionSupported(final int funcType)
功能:是否支持指定方法
说明:某些SDK具有打开关闭浮动工具栏、进入用户中心、进入论坛等功能,该方法可以用来判断是否支持,方便游戏中进行判断. 指定方法的定义请参见SDK库com.quicksdk.FuncType的定义
案例:
Extend.getInstance().isFunctionSupported(FuncType.HIDE_TOOLBAR); //是否支持隐藏悬浮框功能
类名:com.quicksdk.Extend
方法:public String callFunction(final Activity activity, final int funcType)
功能:调用指定方法
说明:某些渠道有显示/隐藏悬浮按扭、进入用户中心、进入论坛等功能,该方法可以用来调用第三方渠道支持的方法,调用前请先用isFunctionSupported进行判断。
案例:
Extend.getInstance().callFunction(activity, FuncType.HIDE_TOOLBAR); //调用隐藏悬浮框的方法
类名:com.quicksdk.Extend
方法:public void callPlugin(final Activity activity, final int funcType,final Object ... infos)
功能:调用显示客服插件的方法
说明:母包实现按钮调用该方法,然后到QuickSDK后台添加客服插件(QuickSDKCustomService)进行打包。
案例:
Extend.getInstance().callPlugin(MainActivity.this, FuncType.CUSTOM, "1000","嘻嘻哈哈","zzzz","1");//后四个参数请依次传入 角色id,角色名,区服名,vip等级
ShareInfo类字段说明
参数名称
数据类型
说明
title
string
分享标题
content
string
分享内容
imgPath
string
分享图片本地地址
imgUrl
string
分享图片网络地址
url
string
分享链接
type
string
分享类型
shareTo
string
分享到哪里
extenal
string
额外备注
类名:com.quicksdk.Extend
方法:public void callFunctionWithParams(final Activity activity, final int funcType,final Object ... infos)
功能:调用渠道的含参方法
说明:以下案例已分享为例 母包调用接口传入分享对象,打出对应渠道包之后即可调起对应渠道的分享功能。
案例:
Extend.getInstance().callFunctionWithParams(MainActivity.this, FuncType.SHARE,shareInfo);
说明:callback的onSuccess将返回封装的json实体;uid (表示用户id),age (表示年龄, 如果渠道没返回默认为-1),realName (是否已实名: true表示已实名, false表示未实名;如果渠道没返回默认为 false),resumeGame (渠道实名认证失败之后是否可以继续游戏 :true表示可以, false表示不可以;如果渠道没返回默认为 true),other (预留字段,如果渠道没返回默认为""的字符串)
返回数据示例:
{"uid":"jc453530202","resumeGame":true,"realName":false,"other":"","age":-1}
案例:
private void verifyRealName() { final Activity activity = this; activity.runOnUiThread(new Runnable() { @Override public void run() { // 判断渠道是否支持实名认证功能 if (Extend.getInstance().isFunctionSupported(FuncType.REAL_NAME_REGISTER)) { Extend.getInstance().callFunctionWithParamsCallBack(activity, FuncType.REAL_NAME_REGISTER, new BaseCallBack() { @Override public void onSuccess(Object... arg0) { if (arg0 != null && arg0.length > 0) { JSONObject jsonObject = (JSONObject) arg0[0]; Log.d("json", "==========" + jsonObject.toString()); try { // 用户id String uid = jsonObject.getString("uid"); // 年龄, 如果渠道没返回默认为-1 int age = jsonObject.getInt("age"); // 是否已实名 true表示已实名 // false表示未实名,如果渠道没返回默认为false boolean realName = jsonObject.getBoolean("realName"); // oppo实名认证失败之后是否可以继续游戏 true表示可以 // false表示不可以,如果渠道没返回默认为true boolean resumeGame = jsonObject.getBoolean("resumeGame"); // 预留字段,如果渠道没返回默认为""的字符串 String other = jsonObject.getString("other"); // 游戏根据返回信息做对应的逻辑处理 } catch (JSONException e) { } } } @Override public void onFailed(Object... arg0) { } }); } } }); }
详细操作见文档:游戏如何调用QuickSDK的隐私弹窗
QuickSDK 已经经过了混淆,如果要混淆java代码,请不要混淆联编的jar包中的类。可以添加以下类到proguard配置,排除在混淆之外:
-keep class com.quicksdk.** { *; }
当游戏当游戏需要设置渠道相关的参数时。可以通过Quick后台添加自定义参数,在渠道列表中配置对应的值,最后通过Extend.getInstance().getExtrasConfig(String key)可以获取到该值。
所有接口接入完成后,生成的母包,应严格按照母包测试用例进行测试,测试通过后,方可打出正确的渠道包。
李先生:13880511661
QQ:48157910
赵先生:15390049857
QQ:1077535763
孙女士:13551010407
QQ:1799614139
QQ群:698731538