【悦声】Android SDK对接文档
一、工程配置
-
引入工程
AndroidStudio用户将lib目录下的aar文件拷贝到自己的项目lib下,加以引用即可! Eclipse用户请自行百度,添加对应的依赖
-
其他資源添加(如果有则按以下目录规则添加即可)
assets的资源直接复制即可;
-
SDK下载地址
1.权限配置
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" ></uses>
<uses-permission android:name="android.permission.WRITE_SETTINGS" ></uses>
<uses-permission android:name="android.permission.VIBRATE" ></uses>
<uses-permission android:name="android.webkit.permission.PLUGIN" ></uses>
<uses-permission android:name="android.permission.INTERNET" ></uses>
<uses-permission android:name="android.permission.SEND_SMS" ></uses>
<uses-permission android:name="android.permission.READ_SMS" ></uses>
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" ></uses>
<uses-permission android:name="android.permission.RECEIVE_MMS" ></uses>
<uses-permission android:name="android.permission.RECEIVE_SMS" ></uses>
<uses-permission android:name="android.permission.READ_PHONE_STATE" ></uses>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" ></uses>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" ></uses>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" ></uses>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" ></uses>
<uses-permission android:name="android.permission.RESTART_PACKAGES" ></uses>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" ></uses>
<uses-permission android:name="android.permission.GET_TASKS" ></uses>
<uses-permission android:name="android.permission.RECORD_AUDIO" ></uses>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" ></uses>
4、Application接入(注意:请务必接入)
游戏方自身的Application对应的方法中实现以下四个方法:
- onCreate 方法:
onApplicationCreate(Application application)
- attachBaseContext 方法:
onApplicationAttachBaseContextInApplication(Application application, Context base)
- onConfigurationChanged 方法:
onApplicationConfigurationChanged(Application application, Configuration newConfig)
- onTerminate 方法:
onApplicationTerminate(Application application)
示例如下:
/**
* 必须要自定义一个application 并且要在manifest中声明, 其中所有方法要在super后面调用
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
YsUnionSdk.getInstance().onApplicationCreate(this);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
YsUnionSdk.getInstance().onApplicationAttachBaseContextInApplication(this, base);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
YsUnionSdk.getInstance().onApplicationConfigurationChanged(this, newConfig);
}
@Override
public void onTerminate() {
super.onTerminate();
YsUnionSdk.getInstance().onApplicationTerminate(this);
}
}
注意:记得在manifest中声明自定义的Application
二、SDK接口调用
1.AndroidManifest.xml文件的配置(必接)
<menifest>
<application>
...
<!-- 聚合sdk -->
<!-- 请务必接入 我方SDK闪屏Activity -->
<activity
android:name="com.yssdk.base.communal.element.SplashScreenActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 是否有闪屏图片 固定-->
<meta-data
android:name="sdk_ys_splash_pic"
android:value="false" />
<!-- cp的启动Activity -->
<meta-data
android:name="sdk_ys_entryactivity"
android:value="cp的启动Activity" />
<!-- sdk对接类 固定-->
<meta-data
android:name="sdk_ys_userimp"
android:value="com.yssdk.sdk.channel.YsChannel" />
<!--游戏名称 我方运营提供-->
<meta-data
android:name="sdk_ys_game_name"
android:value="SDK测试" />
<!--游戏ID,我方运营提供-->
<meta-data
android:name="sdk_ys_main_game_id"
android:value="90" />
<!-- 自己渠道sdk的appid 我方运营提供-->
<meta-data
android:name="sdk_ys_sub_game_id"
android:value="576" />
<!-- 自己渠道sdk的appkey 我方运营提供-->
<meta-data
android:name="sdk_ys_app_key"
android:value="%167%173%217%102%105%158%172%194%210%144%153%167%216%221%168%145%101%157%218%196%160%97%152%158%219%221%167%146%148%164%168%147" />
<!--打包ID,固定-->
<meta-data
android:name="sdk_ys_package_id"
android:value="1" />
<!--现网填true 测试网填false-->
<meta-data
android:name="sdk_ys_online"
android:value="true" />
<!--投放系统->监测链接->广告包ID-->
<meta-data
android:name="sdk_ys_site_id"
android:value="1001" />
<!--投放系统->监测链接->投放标签-->
<meta-data
android:name="sdk_ys_pfname"
android:value="yuesheng" />
<!--我方SDK组件-->
<activity
android:name="com.yssdk.sdk.LoginActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:launchMode="singleTask"
android:hardwareAccelerated="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
android:windowSoftInputMode="adjustPan" />
<service android:name="com.yssdk.sdk.CallbackResultService" />
<service
android:name="com.yssdk.sdk.ui.floatView.FloatBallService"
android:exported="false" />
<activity
android:name="com.yssdk.sdk.CommonWebviewActivity"
android:configChanges="orientation|screenSize|keyboardHidden" />
<activity
android:name="com.yssdk.base.communal.element.YsChaActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity
android:name="com.yssdk.base.communal.element.NoticeActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity
android:name="com.yssdk.sdk.PaymentActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/yssdk_gift_dialog" />
<activity
android:name="com.yssdk.sdk.ui.ActicitySide"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
</application>
</menifest>
2.SDK初始化(必接)
接口:YsUnionSdk.getInstance().initSDK(Activity activity, YsSdkListener listener);
接口示例:
private void initSdk() {
Log.i(TAG, "initSdk...");
// init方法只能在主Activity的onCreate中调用,第二个参数为全局回调
YsUnionSdk.getInstance().initSDK(activity, new YsSdkListener() {
@Override
public void initSuc(String msg) {
initSuc = true;
YsUnionSdk.getInstance().loginSDK(activity);
Log.e(TAG, "收到回调初始化成功: " + msg);
Log.e(TAG, "收到回调初始化成功: " + msg);
}
@Override
public void initFailed(String reason) {
initSuc = false;
Log.e(TAG, "收到回调初始化失败: " + reason);
}
@Override
public void onLoginSuc(String data) {
Log.e(TAG, "收到回调登录成功 " + data);
try {
JSONObject jsonObject = new JSONObject(data);
String cur_uid = jsonObject.getString("userId");//服务端登录验证使用,账号唯一标识, 建议和渠道id拼接作为唯一标识,避免多渠道渠道userId重复.某些渠道此字段可能有点长,建议留100位保存.
String new_sign = jsonObject.getString("new_sign");//服务端登录验证使用
String timestamp = jsonObject.getString("timestamp");//服务端登录验证使用
String cp_ext = jsonObject.getString("cp_ext");//服务端登陆验证使用,这是一个json, 目前写死为{"test":"test"}
String guid = jsonObject.getString("guid");//服务端登陆验证使用
String channelId = jsonObject.getString("channelId");//渠道id 如联想为15 具体参见<各渠道参数>
String channelVersion = jsonObject.getString("channelVersion");//渠道版本
String packageId = jsonObject.getString("packageId");//包id.对应一个游戏安装包.
String age = jsonObject.getString("age");//年龄
String realNameStatus = jsonObject.getString("realNameStatus");//实名状态 0:未实名:1:已实名
String isVisitors = jsonObject.getString("isVisitors");//是否游客 0:不是 ,1:游客
//上面的参数,每次登录成功一定会返回。所以可用getString方法获取.
userId = cur_uid;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onLoginFailed(String reason) {
Log.e(TAG, "收到回调登录失败 " + reason);
userId = "";
}
@Override
public void onLogout(boolean shouldRelogin) {
Log.e(TAG, "收到回调登出 " + shouldRelogin);
userId = "";
if (shouldRelogin) {
// 1.退出游戏场景,回到游戏主界面。 TODO
// 2.重新调起sdk登录
YsUnionSdk.getInstance().loginSDK(activity);
} else {
// 1 退出游戏场景,回到游戏主界面。
// 2 不需主动再调用sdk登录, 但需要有用户点击主界面能调起sdk登录的功能.
}
}
@Override
public void onPaySuc(String extension) {
Log.e(TAG, "收到回调支付成功:" + extension);
}
@Override
public void onPayFail(String extension) {
Log.e(TAG, "收到回调支付失败:" + extension);
}
@Override
public void onExit() {
Log.e(TAG, "收到回调退出 onExit");
// 上报角色信息 TODO
YsUnionSdk.getInstance().submitDataSDK(activity, createUserPrams(YsUserExtraData.TYPE_EXIT_GAME));
//清理资源 杀死进程 TODO
finish();
System.exit(0);
}
@Override
public void onResult(int code, String msg) {
Log.e(TAG, "收到回调其他 code=" + code + " msg=" + msg);
}
});
}
3.登陆(必接)
接口:YsUnionSdk.getInstance().loginSDK(Activity activity)
回调结果onLoginSuc(String json)解析之后的数据如下
参数 | 类型 | 说明 |
---|---|---|
userId | String | 服务端登录验证使用,账号唯一标识, 建议和渠道id拼接作为唯一标识,避免多渠道渠道userId重复.某些渠道此字段可能有点长,建议留100位保存. |
new_sign | String | 服务端登录验证使用 |
timestamp | String | 服务端登录验证使用 |
cp_ext | String | 服务端登陆验证使用,这是一个json, 目前写死为{“test”:”test”} |
guid | String | 服务端登陆验证使用 |
channelId | String | 渠道id |
channelVersion | String | 道版本 |
age | String | 年龄 |
realNameStatus | String | 实名状态 0:未实名:1:已实名 |
isVisitors | String | 是否游客 0:不是 ,1:游客 |
4.支付(必接)
接口:YsUnionSdk.getInstance().paySDK(Activity activity, YsUnionPayParams params)
支付参数YsUnionPayParam获取示例:
private YsUnionPayParams createPayParams() {
orderId = orderId + "_";
YsUnionPayParams payParams = new YsUnionPayParams();
payParams.setBuyNum(1);// 一般只买一份
// cp测试回调写 https://rh-api.hnjst.cn/success.php
payParams.setCallBackUrl("https://rh-api.hnjst.cn/success.php");
payParams.setExtension("回传参数");
payParams.setOrderId(orderId);//cp的订单id
payParams.setPartyName("武当派");
payParams.setPer_price(1);// 单位为分, 但只支持元为单位,所以传100的整数
payParams.setProductDesc("一锭做工完美的金元宝");
payParams.setProductId("11100");
payParams.setProductName("元宝");
payParams.setRatio(10);// 1人民币 10个
payParams.setRemainCoinNum(5000);// 此玩家钱袋里还有5000个元宝
payParams.setRoleId("123");
payParams.setRoleLevel(100);
payParams.setRoleName("悟饭");
payParams.setServerId("1");
payParams.setServerName("华中区");
payParams.setTime(System.currentTimeMillis());// 13位毫秒
payParams.setTotalPrice(1); // 总价格 = 购买份数 * 单价
payParams.setVip(12 + "");
String gsonToString = GsonUtil.GsonToString(payParams);
Log.d(TAG, "支付参数:" + gsonToString);
return payParams;
}
支付结果会在初始化监听回调中返回,onPaySuc(String extension)回调支付成功,onPayFail(String extension)回调支付失败结果;
5.账号切换与注销(必接)
接口:YsUnionSdk.getInstance().logoutSDK(Activity activity, boolean isRelogin)
其中参数:isRelogin表示是否重新拉起登陆的意思,调用注销或者切换的逻辑为:玩家在悬浮窗、或者游戏内设置中点击注销账号,应回到游戏登陆界面,最后重新拉起登陆;如果isRelogin设置为false,需要cp方手动拉起登陆界接口!
6.游戏数据上报(必接)
接口:YsUnionSdk.getInstance().submitDataSDK(Activity activity, YsUserExtraData params)
YsUserExtraData数据获取示例:
// 上报参数
private YsUserExtraData createUserPrams(int type) {
YsUserExtraData userExtraData = new YsUserExtraData();
// 设置上报类型
userExtraData.setDataType(type);
userExtraData.setServerId("1");//玩家所在服务器的ID
userExtraData.setServerName("华中区");//玩家所在服务器的名称
userExtraData.setRoleId("123456789111");//玩家角色ID
userExtraData.setRoleName("悟饭");//玩家角色名称 若无则传"无"
userExtraData.setRoleLevel(100);//玩家角色等级
userExtraData.setProfessionId(2);//当前玩家职业id
userExtraData.setProfession("刺客");//当前玩家职业名称 若无,传入"无"
userExtraData.setPower(10000);//战斗力
userExtraData.setVip(5);//玩家VIP等级
userExtraData.setRoleGender("女");//角色性别 (男或女)
userExtraData.setPayTotal(2000);// 累计充值金额 元为单位
userExtraData.setRemainCoinNum(5000);// 1级货币余额,此玩家钱袋里还有5000个元宝.
userExtraData.setPartyId(1);//帮派id
userExtraData.setPartyName("武当派");//帮派名称 若无,传入"无"
userExtraData.setPartyRoleId(1);//角色在帮派中的称号id
userExtraData.setPartyRoleName("武当-大师兄");// 角色在帮派中的称号 若无,传入"无"
userExtraData.setRoleCreateTime((int) (System.currentTimeMillis() / 1000));//10位 秒
// 人民币能买到的货币统计(传json) 若无则传0
JSONArray balancelist = new JSONArray();
JSONObject balance1 = new JSONObject();// 1级货币
JSONObject balance2 = new JSONObject();// 2级货币
try {
balance1.put("balanceid", "1");
balance1.put("balancename", "元宝");
balance1.put("balancenum", "5000");
balance2.put("balanceid", "2");
balance2.put("balancename", "钻石");
balance2.put("balancenum", "100");
} catch (JSONException e) {
e.printStackTrace();
}
balancelist.put(balance1).put(balance2);
userExtraData.setBanlance(balancelist.toString());
//userExtraData.setBanlance("0");//若无则传0
// 此角色的好友关系(传json) 若无好友则传"无"
JSONArray friendlist = new JSONArray();
JSONObject friend1 = new JSONObject();
JSONObject friend2 = new JSONObject();
try {
friend1.put("roleid", "150");//关系角色id
friend1.put("intimacy", "100");//亲密度
friend1.put("nexusid", "1");//1:夫妻,2:结拜,3:情侣,4:师徒 ,5:仇人;其余关系从6开始自定义编号 不能为空
friend1.put("nexusname", "夫妻");//
friend2.put("roleid", "151");
friend2.put("intimacy", "2");
friend2.put("nexusid", "6");//自定义关系id为6
friend2.put("nexusname", "师兄弟");//自定义关系名称:师兄弟
} catch (JSONException e) {
e.printStackTrace();
}
friendlist.put(friend1).put(friend2);
userExtraData.setFriendShip(friendlist.toString());
//userExtraData.setFriendShip("无");//若无好友关系则传无
/* 以上都为常规参数,各个上报事件都需要传. 选择服务器,创角的时候肯定很多参数是没有的,那么只传已经存在参数 */
/** 上报类型为TYPE_LEVEL_UP 的时候传下面的参数 **/
userExtraData.setRoleLevelUpTime((int) (System.currentTimeMillis() / 1000));// 10位秒
/**
* 上报类型为TYPE_TASK 的时候传下面的参数 任务统计 (任务完成时,不管是成功还是失败)
*/
userExtraData.setTask_id(11);//ID cp定义
userExtraData.setTask_name("追查凶手");
userExtraData.setTask_status(1);// 1:成功 2:失败
/**
* 上报类型为TYPE_HONOR 的时候传下面的参数 荣誉统计(一个角色可以获得多个荣誉 如:排行榜多少名、xx勋章、称号)
*/
userExtraData.setHonor_id(1);//ID cp定义
userExtraData.setHonor_name("晋升副掌门");
String gsonToString = GsonUtil.GsonToString(userExtraData);
Log.d(TAG, "上报参数:" + gsonToString);
return userExtraData;
}
7.退出接口(必接)
接口:YsUnionSdk.getInstance().exitSDK(Activity activity)
退出回调会在onExit()中返回,请在此回调方法中处理游戏退出的相关逻辑;
8.获取实名信息(选接)
接口:YsUnionSdk.getInstance().onGetRealNameInfo(Activity activity, RealNameCallback callback)
9. 获取SDK生成的设备识别码(选接)
接口:YsUnionSdk.getInstance().getUtma(Context context)
10.主Activity声明周期(必接)
请务必尽可能的接入以下生命周期!!
/* 生命周期 全部都要在super后面调用,除了onBackPressed不需要调用super*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
YsUnionSdk.getInstance().onActivityResult(activity, requestCode, resultCode, data);
}
@Override
public void onBackPressed() {
//同步生命周期
YsUnionSdk.getInstance().onBackPressed(activity);
// 监听返回键调用退出接口
YsUnionSdk.getInstance().exitSDK(activity);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
YsUnionSdk.getInstance().onConfigurationChanged(activity, newConfig);
}
@Override
protected void onStart() {
super.onStart();
YsUnionSdk.getInstance().onStart(activity);
}
@Override
protected void onPause() {
super.onPause();
YsUnionSdk.getInstance().onPause(activity);
}
@Override
protected void onResume() {
super.onResume();
YsUnionSdk.getInstance().onResume(activity);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
YsUnionSdk.getInstance().onNewIntent(activity, intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
YsUnionSdk.getInstance().onRequestPermissionsResult(activity, requestCode, permissions, grantResults);
}
@Override
protected void onStop() {
super.onStop();
YsUnionSdk.getInstance().onStop(activity);
}
@Override
protected void onDestroy() {
super.onDestroy();
YsUnionSdk.getInstance().onDestroy(activity);
}
@Override
protected void onRestart() {
super.onRestart();
YsUnionSdk.getInstance().onRestart(activity);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
YsUnionSdk.getInstance().onWindowFocusChanged(activity, hasFocus);
}
详细,请参考DEMO示例!
详细,请参考DEMO示例!
详细,请参考DEMO示例!
FQA:
- 由于目前渠道审核制度严格,请务必在我方弹出隐私协议窗口之后在获取相关设备信息(OAID、IMEI、AndroidID等)
- 请务必在我方SDK初始化成功之后,方可操作其他接口操作、否则会产生不可预料的闪退等问题;