Žiadny popis

#Suyghur 11333d4d89 demo增加浮标切换回调 2 rokov pred
demo 11333d4d89 demo增加浮标切换回调 2 rokov pred
gradle 78cd6f9bb6 demo开发 3 rokov pred
zkeystore 78cd6f9bb6 demo开发 3 rokov pred
.gitignore 78cd6f9bb6 demo开发 3 rokov pred
LICENSE a07aecdee4 Initial commit 3 rokov pred
README.md 309550aeb1 修改README 3 rokov pred
build.gradle 78cd6f9bb6 demo开发 3 rokov pred
gradle.properties 78cd6f9bb6 demo开发 3 rokov pred
gradlew 78cd6f9bb6 demo开发 3 rokov pred
gradlew.bat 78cd6f9bb6 demo开发 3 rokov pred
keystore.properties 78cd6f9bb6 demo开发 3 rokov pred
settings.gradle 78cd6f9bb6 demo开发 3 rokov pred

README.md

修订记录

日期 版本 说明 作者
2021-10-29 1.0.0 文档建立 麦锦培
2021-11-10 1.0.1 1)SDK开放获取QS_GCP_ID能力
2)增加浮标切换账号回调
麦锦培

1.接入准备

服务端文档

客户端SDK接入Demo工程

引入SDK配置

  • 游戏资源文件名、布局名、布局id名等建议使用规范命名,避免和SDK资源冲突
  • Android Gradle Plugin Version : 4.1.3+
  • Gradle Version : 6.5+
  • 拷贝SDK目录下assets/supplierconfig.jsonzlsioh.dat到项目的assets中
  • 拷贝SDK目录下assets/qs_game至项目中,并修改qs_cfg.properties文件的值
QS_PACKAGE_VERSION=出包时间,如20210101
QS_CAMPAIGN_ID=我方提供的分别标识
QS_APP_ID=我方提供的appid
QS_APP_KEY=我方提供的appkey
QS_OWN_DEBUG=false(true为测试模式,可以看到接口日志弹窗信息)
QS_GCP_ID=非必要,按需填写,SDK不会根据这个值做任何逻辑
QS_ONLINE_ENV=按我方提供的填写即可(固定值)

引入SDK

  • 在应用build.gradledependencies节点下添加SDK依赖,目前只提供远程依赖,需要离线aar包请联系我方技术

    在项目级build.gradle文件下的allprojects节点下添加仓库的url

    	allprojects {
    		repositories {
    			...
    			mavenCentral()
    			...
    		}
    	}
    

    在应用级build.gradle文件下的allprojects节点下添加仓库的url

    	// 打点组件SDK
    	implementation 'io.github.yyxxgame.sdk:qingshi-gamesdk-analytics:2.0.0-rc1'
    	// 支付组件SDK
    	implementation 'io.github.yyxxgame.sdk:qingshi-gamesdk-billing:2.0.0-rc1'
    	// 登录组件SDK
    	implementation 'io.github.yyxxgame.sdk:qingshi-gamesdk-login:2.0.0-rc1'
    	// 核心组件SDK
    	implementation 'io.github.yyxxgame.sdk:qingshi-gamesdk-core:2.0.0-rc1'
    

配置游戏AndroidManifest.xml

  • 配置游戏AndroidManifest.xml的首个启动Activity为SDK的WelcomeActivity
	<activity
		android:name="cn.qingshi.gamesdk.base.WelcomeActivity"
		android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
		android:launchMode="standard"
		android:screenOrientation="游戏实际屏幕方向"
		android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
		<intent-filter>
			<action android:name="android.intent.action.MAIN" />
			<category android:name="android.intent.category.LAUNCHER" />
		</intent-filter>
</activity>
  • 修改AndroidManifest.xml中游戏Activity的intent-filter属性,假设DemoActivity为游戏的Activity,则需要修改action标签的adnroid:name为游戏的包名
	<activity
	android:name="com.gamesdk.qingshi.DemoActivity"
	android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
	android:exported="true"
	android:launchMode="singleTask"
	android:screenOrientation="sensorLandscape">
	<intent-filter>
		<action android:name="游戏包名" />
		<category android:name="android.intent.category.DEFAULT" />
	</intent-filter>
</activity>

混淆配置

  • SDK已经经过混淆,SDK内部个别方法使用到了反射,建议不做混淆,如必须开启混淆,请参考并添加以下混淆配置
-keep class cn.qingshi.gamesdk.**{*;}

# support sdk
-keep class cn.yyxx.support.**{*;}

# msa sdk
-keep class XI.**{*;}
-keep class com.asus.**{*;}
-keep class com.bun.**{*;}
-keep class com.huawei.hms.ads.identifier.**{*;}
-keep class com.samsung.android.deviceidservice.**{*;}
-keep class com.netease.nis.sdkwrapper.** {*;}
-keep class com.zui.**{*;}
-keep class org.json.**{*;}

# authsdk
-keep class com.alibaba.**{*;}
-keep class com.cmic.**{*;}
-keep class com.mobile.**{*;}
-keep class com.nirvana.**{*;}

# mmkv
-keep class com.tencent.mmkv.**{*;}

# zap
-keep class com.dolin.zap.**{*;}

# v4-support
-keep class android.support.**{*;}

2.接口说明

SDK的所有接口如无特殊说明,默认均为必接且请务必在游戏主线程调用

1)同步Application中的生命周期

需要在游戏的Application类的attachBaseContext()onCreate()中实现SDK方法

public class DemoApplication extends Application {

	@Override
	protected void attachBaseContext(Context base) {
		super.attachBaseContext(base);
		QSGameSdk.getInstance().attachBaseContext(this, base);
	}

	@Override
	public void onCreate() {
		super.onCreate();
		QSGameSdk.getInstance().initApplication(this);
	}
}

2)同步游戏Activity中各个生命周期

  • 同步onStart
	@Override
	protected void onStart() {
		super.onStart();
		QSGameSdk.getInstance().onStart(this);
	}
  • 同步onResume
	@Override
	protected void onResume() {
		super.onResume();
		QSGameSdk.getInstance().onResume(this);
	}
  • 同步onRestart
	@Override
	protected void onRestart() {
		super.onRestart();
		QSGameSdk.getInstance().onReStart(this);
	}
  • 同步onPause
	@Override
	protected void onPause() {
		super.onPause();
		QSGameSdk.getInstance().onPause(this);
	}
  • 同步onStop
	@Override
	protected void onStop() {
		super.onStop();
		QSGameSdk.getInstance().onStop(this);
	}
  • 同步onDestroy
	@Override
	protected void onDestroy() {
		super.onDestroy();
		QSGameSdk.getInstance().onDestroy(this);
	}
  • 同步onActivityResult
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		QSGameSdk.getInstance().onActivityResult(this, requestCode, requestCode, data);
	}
  • 同步onNewIntent
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		QSGameSdk.getInstance().onNewIntent(this, intent);
	}

3)SDK通用回调接口ICallback说明

	public interface ICallback {
		void onResult(int code, String result);
	}
参数 类型 说明
code int 状态码(0成功,-1失败)
result string 返回信息

4)SDK初始化

  • 在游戏的主Activity的onCreate中调用
	/**
	 * SDK初始化
	 *
	 * @param activity    Activity上下文
	 * @param isLandscape 是否横屏
	 * @param callback    SDK初始化回调
	 */
	public void initialize(final Activity activity, final Boolean isLandscape, ICallback callback)
  • 示例
	@Override
	protected void onCreate(Bundle savedInstanceState){
		QSGameSdk.getInstance().initialize(this, false, new ICallback() {
			@Override
			public void onResult(int code, String result) {
				if (code == 0) {
					//TODO SDK初始化成功
				} else {
					//TODO SDK初始化失败,result是失败的debug信息
				}
			}
		});
	}

5)用户账号登录

	/**
	 * SDK用户登录
	 *
	 * @param activity Activity上下文
	 * @param callback 登录回调对象
	 */
	public void login(Activity activity, ICallback callback)

登录回调返回的result信息

参数 类型 说明
open_id string SDK的用户ID
game_token string 签名token
  • 示例
	QSGameSdk.getInstance().login(this, new ICallback(){
		@Override
		public void onResult(int code, String result) {
			if (code == 0) {
				//TODO 对SDK返回的用户信息进行验签
				//result返回的是JSON字符串,可以得到open_id和game_token等信息
				//签名规则详见服务端接入文档
			} else {
				//TODO 登录失败,result是返回的debug信息
			}
		}
	});

6)用户账号登出

用户在游戏中触发登出,游戏回到选服界面重新拉起登录

	/**
	 * SDK用户登出账号
	 *
	 * @param activity Activity上下文
	 * @param callback 登出回调对象
	 */
	public void logout(Activity activity, ICallback callback)
  • 示例
	QSGameSdk.getInstance().logout(this, new ICallback() {
		@Override
		public void onResult(int code, String result) {
			if (code == 0) {
				//TODO 用户登出成功,登出成功后请返回游戏选服界面,然后调用SDK的登录接口拉起登录框
			} else {
				//TODO 用户登出失败,result是返回的debug信息
			}
		}
	});

7)角色信息上报

请务必根据当前角色的触发的事件进行上报

角色信息实体对象QSRoleInfo,如无特别说明所有字段均不能为null或空串""

参数 类型 说明
openId string 当前用户ID
serverNo string 当前角色所在的服务器ID
serverName string 当前角色所在的服务器名
roleId string 当前角色ID
roleName string 当前角色名
roleLevel string 当前角色等级
roleGender string 当前角色性别,如无默认传男
balance string 当前角色游戏币余额,若无传"0"
power string 当前角色战力,若无传"0"
vipLevel string 当前Vip角色等级,若无传"0"
roleCTime string 当前角色创建的时间戳(10位),角色一旦创建则是固定值
roleLevelMTime string 当前角色升级的时间戳(10位),如果是创角则传创角时间,如果是角色登录则传入上一次角色等级变化的时间
ext string 扩展参数,不需要则传入空字符串""

角色创建

	/**
	 * SDK角色创建信息上报
	 *
	 * @param activity Activity上下文
	 * @param roleInfo 角色信息实体
	 */
	public void roleCreate(Activity activity, QSRoleInfo roleInfo)

角色进入服务器(角色登录)

	/**
	 * SDK角色登录信息上报
	 *
	 * @param activity Activity上下文
	 * @param roleInfo 角色信息实体
	 */
	public void roleLauncher(Activity activity, QSRoleInfo roleInfo)

角色升级

	/**
	 * SDK角色升级信息上报
	 *
	 * @param activity Activity上下文
	 * @param roleInfo 角色信息实体
	 */
	public void roleUpgrade(Activity activity, QSRoleInfo roleInfo)
  • 示例
	QSRoleInfo gameRoleInfo = new QSRoleInfo();
	// 用户ID
	gameRoleInfo.setOpenId("用户ID");
	// 服务器ID
	gameRoleInfo.setServerNo("服务器ID");
	// 服务器名
	gameRoleInfo.setServerName("服务器名");
	// 角色ID
	gameRoleInfo.setRoleId("角色id");
	// 角色名称
	gameRoleInfo.setRoleName("角色名称");
	// 角色等级
	gameRoleInfo.setRoleLevel("角色等级");
	// 角色性别,无该字段则传"男"
	gameRoleInfo.setRoleGender("角色性别");
	// 当前角色游戏币余额,无该字段则传"0"
	gameRoleInfo.setBalance("当前角色游戏币余额");
	// 当前角色战力,无该字段则传"0"
	gameRoleInfo.setPower("当前角色战力");
	// 用户VIP等级,无该字段则传"0"
	gameRoleInfo.setVipLevel("用户VIP等级");
	// 创角时间戳(角色一旦创角则是固定值)
	gameRoleInfo.setRoleCTime("创角10位时间戳")
	// 角色等级变化时间戳
	gameRoleInfo.setroleLevelMTime("角色等级变化时间戳")
	// 扩展字段
	gameRoleInfo.setExt("扩展字段");

	//角色创建
	QSGameSdk.getInstance().roleCreate(this, gameRoleInfo);

	//角色登录
	QSGameSdk.getInstance().roleLauncher(this, gameRoleInfo;

	//角色升级
	QSGameSdk.getInstance().roleUpgrade(this, gameRoleInfo;

8)支付储值

请务必保证调用角色信息上报中的角色登录上报后再调用 客户端SDK回调的只是支付流程的结果,实际支付结果将由服务端回调

支付信息实体对象QSChargeInfo,如无特别说明所有字段均不能为null或空串""

参数 类型 说明
openId string 当前用户ID
serverNo string 当前角色所在的服务器ID
serverName string 当前角色所在的服务器名
roleId string 当前角色ID
roleName string 当前角色名
roleLevel string 当前角色等级
roleGender string 当前角色性别,如无默认传男
balance string 当前角色游戏币余额,若无传"0"
power string 当前角色战力,若无传"0"
vipLevel string 当前Vip角色等级,若无传"0"
cpOrderId string 游戏订单号
productName string 商品名称
amount int 金额,单位分
cpCallbackInfo string 透传信息,该字段内容会原样在服务端接口返回
	/**
	 * SDK用户支付
	 *
	 * @param activity   Activity上下文
	 * @param chargeInfo 支付信息实体对象
	 * @param callback   支付回调对象
	 */
	public void charge(Activity activity, QSChargeInfo chargeInfo,ICallback callback)
  • 示例
	QSChargeInfo gameChargeInfo = new QSChargeInfo();
	// 用户ID
	gameChargeInfo.setOpenId("用户ID");
	// 服务器ID
	gameChargeInfo.setServerNo("服务器ID");
	// 服务器名
	gameChargeInfo.setServerName("服务器名");
	// 角色ID
	gameChargeInfo.setRoleId("角色id");
	// 角色名称
	gameChargeInfo.setRoleName("角色名称");
	// 角色等级
	gameChargeInfo.setRoleLevel("角色等级");
	// 角色性别,无该字段则传"男"
	gameChargeInfo.setRoleGender("角色性别");
	// 当前角色游戏币余额,无该字段则传"0"
	gameChargeInfo.setBalance("当前角色游戏币余额");
	// 当前角色战力,无该字段则传"0"
	gameChargeInfo.setPower("当前角色战力");
	// 用户VIP等级,无该字段则传"0"
	gameChargeInfo.setVipLevel("用户VIP等级");
	// 游戏订单号
	gameChargeInfo.setCpOrderId("游戏订单号");
	// 商品名称
	gameChargeInfo.setProductName("商品名称")
	// 金额
	gameChargeInfo.setAmount(0)
	// 透传字段
	gameChargeInfo.setCpCallbackInfo("透传字段");

	//客户端SDK回调的只是支付流程的结果,实际支付结果将由服务端回调
	QSGameSdk.getInstance().charge(this, gameChargeInfo , new ICallback() {
		@Override
			public void onResult(int code, String result) {
				if (code == 0) {
					//TODO 支付流程完成
				} else {
					//TODO 支付失败
				}
			}
	});

10)设置SDK浮标用户账号登出回调

建议在SDK初始化成功后设置,该回调会监听用户浮标切换账号的行为,处理逻辑跟logout接口保持一致即可

	/**
	 * 浮标退出回调
	 *
	 * @param activity Activity上下文
	 * @param callback 浮标退出回调对象
	 */
	public void onFloatCenterLogout(Activity activity, ICallback callback)
  • 示例
	QSGameSdk.getInstance().onFloatCenterLogout(this, new ICallback() {
		@Override
		public void onResult(int code, String result) {
			if (code == 0) {
				//TODO 用户浮标登出成功,登出成功后请返回游戏选服界面,然后调用SDK的登录接口拉起登录框
			} else {
				//TODO 用户浮标登出失败,result是返回的debug信息
			}
		}
	});

11)显示SDK退出框(选接)

用户(玩家)按下返回键时调用,接入方需要实现Activity的onKeyDown,并判断keyCode为KeyEvent.KEYCODE_BACK时调用该接口

	/**
	 * 显示退出框
	 *
	 * @param activity Activity上下文
	 * @param callback 退出回调对象
	 */
	public void openExitView(Activity activity, ICallback callback)
  • 示例
	//重写Activity的onKeyDown并判断KeyDown事件
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			QSGameSdk.getInstance().openExitView(this, new ICallback() {
				@Override
				public void onResult(int code, String result) {
					if (code == 0) {
						// 结束当前Activity
						// 如果要杀进程需要在onDestroy中处理,不然会不执行SDK的onDestroy方法
						finish();
					}
				}
			});
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		QSGameSdk.getInstance().onDestroy(this);
		// 结束当前应用进程
		System.exit(0);
	}

12)获取SDK当前用户ID(选接)

	/**
	 * 获取当前SDK用户ID
	 *
	 * @return
	 */
	public String getCurrentOpenId()
  • 示例
	QSGameSdk.getInstance().getCurrentOpenId();

13)获取SDK当前版本(选接)

	/**
	 * 获取当前SDK版本
	 *
	 * @return
	 */
	public String getCurrentSdkVersion()
  • 示例
	QSGameSdk.getInstance().getCurrentSdkVersion();

14)权限请求(选接)

若游戏需要动态请求特殊或危险权限,可以选择使用SDK的权限请求接口,该功能已经适配Android 12的行为变更 SDK内部已经申请了SD卡存储权限及获取设备信息权限

	/**
	 * 权限请求
	 *
	 * @param activity    Activity上下文
	 * @param permissions 权限列表
	 * @param callback    权限请求回调对象
	 */
	public void requestPermission(Activity activity, List<String> permissions, ICallback callback)

  • 示例
	List<String> permissions = new ArrayList<String>() {{
		// 相机摄像头
		add(Permission.CAMERA);
		// 音频麦克风
		add(Permission.RECORD_AUDIO);
	}};
	QSGameSdk.getInstance().requestPermission(activity, permissions, new ICallback() {
		@Override
		public void onResult(int code, String result) {
			if (code == 0) {
				//TODO 授权成功,result是成功授权的权限json字符串
			} else {
				//TODO 授权是白,result是失败授权的权限json字符串
			}
		}
	});

15)日志接口(选接)

若游戏有需要持久化java、kotlin和C++(联系我方技术获取头文件)层的日志,可以使用SDK的日志接口。SDK的日志框架底层使用C++进行开发,使用了Linux系统的mmap内存拷贝技术 SDK会默认缓存3天的日志,过期则自动删除 缓存的文件使用Facebook开源的压缩算法zlib进行压缩 缓存路径为手机内部存储目录/Android/data/包名/files/dolin/zap,即应用的私有目录 更多使用方法请联系我方技术

  • 示例
	// debug日志
	Logger.d(TAG,msg);
	// info日志
	Logger.i(TAG,msg);
	// error日志
	Logger.e(TAG,msg);

16)获取SDK配置文件QS_GCP_ID(选接)

为了方便接入方需要,这个接口可以获取SDK配置文件中的QS_GCP_ID接入方填写的值,SDK不会根据这个值做任何逻辑

	/**
	 * 获取SDK配置文件QS_GCP_ID
	 *
	 * @param context    Context上下文
	 */
	public static void getQsGcpId(Context context)

  • 示例
	// debug日志
	ParamsUtils.getQsGcpId(context);