本来项目是已经接过share sdk 的登陆的 现在要接应用宝支付,为了省事打算直接先接支付试一下,可
是米大师官网的sdk下载不知道什么情况都没法下载,于是就开始了接YSDK的悲催人生,经过一个多星期的
努力demo终于跑了起来,下面跑一遍流程,再总结一下遇到的问题,方便下次接入的时候使用.(没用过
java 没用过eclipse ,对untiy和android的交互也不是特别了解...有错误的地方欢迎指出
1.腾讯开放平台注册应用
得到 qq和微信的Appid和AppKey以及米大师的沙盒测试Appkey
2.下载YSDK
解压之后
我用的是Eclipse Readme是官网给的接入文档
3.导入文件
本来我只是想按照以往的打.jar包导入到unity使用 可是发现这样根本没法调试、没法测试就只能先做个demo 在unity 中把逻辑写好之后导出android包导入Eclipse里面来接(untiy修改东西的话,把导出的android包里的assets里的东西替换一下就ok了)
unity场景,两个text用于debug调试
http://www.xuanyusong.com/archives/676 unity 和android 互传消息参考的雨松MOMO的…
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class test : MonoBehaviour {
public Text t;
public Text t1;
AndroidJavaClass jc;
AndroidJavaObject jo;
public void Awake()
{
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic("currentActivity");
}
public void weixin()
{
t1.text = "weixin Begin call";
jo.Call("Login_WeiXin", "weixin");
t1.text = " weixin call end ";
}
public void qq()
{
t1.text = "qq Begin call";
jo.Call("Login_QQ", "qq");
t1.text = " qq call end ";
}
public void youke()
{
t1.text = "youke Begin call";
jo.Call("Login_YouKe", "youke");
t1.text = " youke call end ";
}
public void Pay()
{
t1.text = "Pay Begin call";
jo.Call("Pay", "111");
t1.text = " pay call end ";
}
public void message(string mess)
{
t.text = mess;
}
}
实际传多个参格式 根据个人需要传
jo.Call(“Pay”, new object[] { zoonID, itemId, itemName, price, num, userId});
导出android包
eclipse–>File –>Import 导出的android包和YSDK-Eclipse 下的library//一定要copy到工作目录下
添加依赖 右键 游戏工程 ->Properties->Android->Add ->Apply就ok 了 Is Library 不要勾选上 会出问题…..不要勾选上….
4.开始接入..
需要把demo里assets里的东西导如到游戏工程assets下面 //我这就一个midaspay 和ysdkconf
ysdkconf里面的东西需要根据自己应用的信息进行修改 三个id ;相当于注释 联调的话就把 ;YSDK_URL=https://ysdktest.qq.com 前的;去掉
YSDK_URL=https://ysdk.qq.com 前面加上;
脚本的话 用到了demo里面的两个脚本 一个wx的,一个Ysdkcallback
需要android-support-v4.jar的话就把demo libs下面的android-support-v4.jar拷贝到项目libs下面
我用的编码格式是utf-8 右键脚本 ->Properties
如果在后面调试的时候汉字出现乱码 改下这个
还有就是res 资源文件 我把demo里的全部copy到里面了 还有libs 下面的 也copy过来了
wx的
package 包命.wxapi;//一定要是包命+.wxapi
/**
* !!此文件的代码逻辑部分使用者不要修改
*/
public class WXEntryActivity extends com.tencent.ysdk.module.user.impl.wx.YSDKWXEntryActivity { }
回调的,没有该什么东西就是改了一下消息发送,主要处理YSDKApi的回调
package 包命;
import android.app.Activity;
import android.util.Log;
import com.tencent.ysdk.framework.common.eFlag;
import com.tencent.ysdk.module.bugly.BuglyListener;
import com.tencent.ysdk.module.pay.PayListener;
import com.tencent.ysdk.module.pay.PayRet;
import com.tencent.ysdk.module.user.PersonInfo;
import com.tencent.ysdk.module.user.UserListener;
import com.tencent.ysdk.module.user.UserLoginRet;
import com.tencent.ysdk.module.user.UserRelationRet;
import com.tencent.ysdk.module.user.WakeupRet;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* TODO GAME 游戏需要根据自己的逻辑实现自己的YSDKCallback对象。
* YSDK通过UserListener抽象类中的方法将授权或查询结果回调给游戏。
* 游戏根据回调结果调整UI等。只有设置回调,游戏才能收到YSDK的响应。
* 这里是Java层回调(设置了Java层回调会优先调用Java层回调, 如果要使用C++层回调则不能设置Java层回调)
*/
public class YSDKCallback implements UserListener, BuglyListener,PayListener {
public static MainActivity mainActivity;
public YSDKCallback(Activity activity) {
mainActivity = (MainActivity) activity;
}
public void OnLoginNotify(UserLoginRet ret) {
Log.d(MainActivity.LOG_TAG,"called");
Log.d(MainActivity.LOG_TAG,ret.getAccessToken());
Log.d(MainActivity.LOG_TAG,ret.getPayToken());
Log.d(MainActivity.LOG_TAG,"ret.flag" + ret.flag);
Log.d(MainActivity.LOG_TAG,ret.toString());
mainActivity.sendResult("Fuck1OnLoginNotify");
// mainActivity.stopWaiting();
switch (ret.flag) {
case eFlag.Succ:
mainActivity.letUserLogin();
break;
// 游戏逻辑,对登录失败情况分别进行处理
case eFlag.QQ_UserCancel:
mainActivity.sendResult("用户取消授权,请重试");
mainActivity.letUserLogout();
break;
case eFlag.QQ_LoginFail:
mainActivity.sendResult("QQ登录失败,请重试");
mainActivity.letUserLogout();
break;
case eFlag.QQ_NetworkErr:
mainActivity.sendResult("QQ登录异常,请重试");
mainActivity.letUserLogout();
break;
case eFlag.QQ_NotInstall:
mainActivity.sendResult("手机未安装手Q,请安装后重试");
mainActivity.letUserLogout();
break;
case eFlag.QQ_NotSupportApi:
mainActivity.sendResult("手机手Q版本太低,请升级后重试");
mainActivity.letUserLogout();
break;
case eFlag.WX_NotInstall:
mainActivity.sendResult("手机未安装微信,请安装后重试");
mainActivity.letUserLogout();
break;
case eFlag.WX_NotSupportApi:
mainActivity.sendResult("手机微信版本太低,请升级后重试");
mainActivity.letUserLogout();
break;
case eFlag.WX_UserCancel:
mainActivity.sendResult("用户取消授权,请重试");
mainActivity.letUserLogout();
break;
case eFlag.WX_UserDeny:
mainActivity.showToastTips("用户拒绝了授权,请重试");
mainActivity.letUserLogout();
break;
case eFlag.WX_LoginFail:
mainActivity.sendResult("微信登录失败,请重试");
mainActivity.letUserLogout();
break;
case eFlag.Login_TokenInvalid:
mainActivity.sendResult("您尚未登录或者之前的登录已过期,请重试");
mainActivity.letUserLogout();
break;
case eFlag.Login_NotRegisterRealName:
// 显示登录界面
mainActivity.sendResult("您的账号没有进行实名认证,请实名认证后重试");
mainActivity.letUserLogout();
break;
default:
// 显示登录界面
mainActivity.sendResult("default");
mainActivity.letUserLogout();
break;
}
}
public void OnWakeupNotify(WakeupRet ret) {
mainActivity.sendResult("Fuck1OOnWakeupNotify");
Log.d(MainActivity.LOG_TAG,"called");
Log.d(MainActivity.LOG_TAG,"flag:" + ret.flag);
Log.d(MainActivity.LOG_TAG,"msg:" + ret.msg);
Log.d(MainActivity.LOG_TAG,"platform:" + ret.platform);
MainActivity.platform = ret.platform;
// TODO GAME 游戏需要在这里增加处理异账号的逻辑
if (eFlag.Wakeup_YSDKLogining == ret.flag) {
// 用拉起的账号登录,登录结果在OnLoginNotify()中回调
} else if (ret.flag == eFlag.Wakeup_NeedUserSelectAccount) {
// 异账号时,游戏需要弹出提示框让用户选择需要登录的账号
Log.d(MainActivity.LOG_TAG,"diff account");
// mainActivity.showDiffLogin();
} else if (ret.flag == eFlag.Wakeup_NeedUserLogin) {
// 没有有效的票据,登出游戏让用户重新登录
Log.d(MainActivity.LOG_TAG,"need login");
mainActivity.letUserLogout();
} else {
Log.d(MainActivity.LOG_TAG,"logout");
mainActivity.letUserLogout();
}
}
@Override
public void OnRelationNotify(UserRelationRet relationRet) {
//登陆相关信息,根据需要传到unity 中实现登陆
// myresult =personInfo.nickName+","+personInfo.openId+","+....
//untiy中 string []userInfo=myresult.Split(',');
//openId userId 根据登陆方式选择relationRet.platform
//1 为qq登陆 openid 2为微信登陆 userid
String result = "";
result = result +"flag:" + relationRet.flag + "\n";
result = result +"msg:" + relationRet.msg + "\n";
result = result +"platform:" + relationRet.platform + "\n";
if (relationRet.persons != null && relationRet.persons.size()>0) {
PersonInfo personInfo = (PersonInfo)relationRet.persons.firstElement();
StringBuilder builder = new StringBuilder();
builder.append("UserInfoResponse json: \n");
builder.append("nick_name: " + personInfo.nickName + "\n");
builder.append("open_id: " + personInfo.openId + "\n");
builder.append("userId: " + personInfo.userId + "\n");
builder.append("gender: " + personInfo.gender + "\n");
builder.append("picture_small: " + personInfo.pictureSmall + "\n");
builder.append("picture_middle: " + personInfo.pictureMiddle + "\n");
builder.append("picture_large: " + personInfo.pictureLarge + "\n");
builder.append("provice: " + personInfo.province + "\n");
builder.append("city: " + personInfo.city + "\n");
builder.append("country: " + personInfo.country + "\n");
result = result + builder.toString();
} else {
result = result + "relationRet.persons is bad";
}
Log.d(MainActivity.LOG_TAG,"OnRelationNotify" + result);
// 发送结果到结果展示界面
mainActivity.sendResult(result);
}
@Override
public String OnCrashExtMessageNotify() {
// 此处游戏补充crash时上报的额外信息
Log.d(MainActivity.LOG_TAG,String.format(Locale.CHINA, "OnCrashExtMessageNotify called"));
Date nowTime = new Date();
SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return "new Upload extra crashing message for bugly on " + time.format(nowTime);
}
@Override
public byte[] OnCrashExtDataNotify() {
return null;
}
@Override
public void OnPayNotify(PayRet ret) {
Log.d(MainActivity.LOG_TAG,ret.toString());
if(PayRet.RET_SUCC == ret.ret){
//支付流程成功
switch (ret.payState){
//支付成功
case PayRet.PAYSTATE_PAYSUCC:
mainActivity.sendResult(
"用户支付成功,支付金额"+ret.realSaveNum+";" +
"使用渠道:"+ret.payChannel+";" +
"发货状态:"+ret.provideState+";" +
"业务类型:"+ret.extendInfo+";建议查询余额:"+ret.toString());
break;
//取消支付
case PayRet.PAYSTATE_PAYCANCEL:
mainActivity.sendResult("用户取消支付:"+ret.toString());
break;
//支付结果未知
case PayRet.PAYSTATE_PAYUNKOWN:
mainActivity.sendResult("用户支付结果未知,建议查询余额:"+ret.toString());
break;
//支付失败
case PayRet.PAYSTATE_PAYERROR:
mainActivity.sendResult("支付异常"+ret.toString());
break;
}
}else{
switch (ret.flag){
case eFlag.Login_TokenInvalid:
mainActivity.sendResult("登录态过期,请重新登录:"+ret.toString());
mainActivity.letUserLogout();
break;
case eFlag.Pay_User_Cancle:
//用户取消支付
mainActivity.sendResult("用户取消支付:"+ret.toString());
break;
case eFlag.Pay_Param_Error:
mainActivity.sendResult("支付失败,参数错误"+ret.toString());
break;
case eFlag.Error:
default:
mainActivity.sendResult("支付异常"+ret.toString());
break;
}
}
}
}
自己的脚本 支付接的道具直购
package ....;
//Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
//Jad home page: http://www.kpdus.com/jad.html
//Decompiler options: packimports(3)
//Source File Name: MainActivity.java
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.tencent.ysdk.api.YSDKApi;
import com.tencent.ysdk.framework.common.BaseRet;
import com.tencent.ysdk.framework.common.eFlag;
import com.tencent.ysdk.framework.common.ePlatform;
import com.tencent.ysdk.module.pay.*;
import com.tencent.ysdk.module.user.UserLoginRet;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
public class MainActivity extends UnityPlayerActivity
{
public static ProgressDialog mAutoLoginWaitingDlg;
public static GridView mModuleListView;
public static LinearLayout mModuleView;
public static LinearLayout mResultView;
public LocalBroadcastManager lbm;
public BroadcastReceiver mReceiver;
public static String title = "";
public static String callAPI = "";
public static String desripton = "";
public static final String LOG_TAG = "YSDK DEMO";
public static final String LOCAL_ACTION = "com.tencent.ysdkdemo";
protected static int platform;
static
{
platform = ePlatform.None.val();
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//requestWindowFeature(1);
//setContentView(0x7f040005);
YSDKApi.onCreate(this);
YSDKApi.setUserListener(new YSDKCallback(this));
YSDKApi.setBuglyListener(new YSDKCallback(this));
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d("YSDK DEMO", "onActivityResult");
super.onActivityResult(requestCode, resultCode, data);
YSDKApi.onActivityResult(requestCode, resultCode, data);
}
protected void onRestart()
{
super.onRestart();
YSDKApi.onRestart(this);
}
protected void onResume()
{
super.onResume();
YSDKApi.onResume(this);
}
protected void onPause()
{
super.onPause();
YSDKApi.onPause(this);
}
protected void onStop()
{
super.onStop();
YSDKApi.onStop(this);
}
protected void onDestroy()
{
super.onDestroy();
YSDKApi.onDestroy(this);
Log.d("YSDK DEMO", "onDestroy");
if(lbm != null)
lbm.unregisterReceiver(mReceiver);
if(mAutoLoginWaitingDlg != null)
mAutoLoginWaitingDlg.cancel();
}
// TODO GAME 在onNewIntent中需要调用handleIntent将平台带来的数据交给YSDK处理
@Override
protected void onNewIntent(Intent intent) {
Log.e(LOG_TAG,"onNewIntent");
super.onNewIntent(intent);
YSDKApi.handleIntent(intent);
}
public String callGetLoginRecord() {
UserLoginRet ret = new UserLoginRet();
int platform = 0;
platform = com.tencent.ysdk.api.YSDKApi.getLoginRecord(ret);
Log.d(MainActivity.LOG_TAG,"ret:"+ ret.toString());
String result = "";
if (platform == ePlatform.PLATFORM_ID_QQ) {
result += "platform = " + ret.platform + " QQ登录 \n";
result += "accessToken = "
+ ret.getAccessToken() + "\n";
result += "payToken = "
+ret.getPayToken() + "\n";
}
result += "openid = " + ret.open_id + "\n";
result += "flag = " + ret.flag + "\n";
result += "msg = " + ret.msg + "\n";
result += "pf = " + ret.pf + "\n";
result += "pf_key = " + ret.pf_key + "\n";
return result;
}
// TODO GAME 在异账号时,模拟游戏弹框提示用户选择登陆账号
//登陆成功之后获取通过ret.platform 获得登陆方式,->获得登陆角色信息-》
//通过回调将用到的角色信息发给unity-》发送登陆请求
public void letUserLogin() {
UserLoginRet ret = new UserLoginRet();
YSDKApi.getLoginRecord(ret);
Log.d(LOG_TAG,"flag: " + ret.flag);
Log.d(LOG_TAG,"platform: " + ret.platform);
sendResult("login");
if(ret.platform==1)
com.tencent.ysdk.api.YSDKApi.queryUserInfo(ePlatform.QQ);
else if(ret.platform==2)
com.tencent.ysdk.api.YSDKApi.queryUserInfo(ePlatform.WX);
if (ret.ret != BaseRet.RET_SUCC) {
Log.d(LOG_TAG,"UserLogin error!!!");
letUserLogout();
return;
}
}
public void letUserLogout() {
YSDKApi.logout();
}
public ePlatform getPlatform() {
UserLoginRet ret = new UserLoginRet();
YSDKApi.getLoginRecord(ret);
if (ret.flag == eFlag.Succ) {
return ePlatform.getEnum(ret.platform);
}
return ePlatform.None;
}
public void Login_QQ(String mess){
System.out.println("QQlogin===QQ");
YSDKApi.login(ePlatform.QQ);
}
public void Login_YouKe(String mess){
System.out.println("YouKelogin===youke");
YSDKApi.login(ePlatform.Guest);
}
public void Login_WeiXin(String mess){
UnityPlayer.currentActivity.runOnUiThread(new Runnable()
{
@Override
public void run() {
YSDKApi.login(ePlatform.WX);
System.out.println("WXlogin===wx");
}});
// YSDKApi.queryUserInfo(getPlatform());
}
public void Pay(String mess)
{
String zoneId = "1";
PayItem item = new PayItem();
item.id = "1";
item.name = "1";
item.desc = "1";
item.price = 1;
item.num = 10;
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),0x7f020014);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] appResData = baos.toByteArray();
String ysdkExt = "ysdkExt";
String midasExt = "midasExt";
YSDKApi.buyGoods(zoneId,item,"输入自己的沙盒appkey",appResData,midasExt,ysdkExt,new YSDKCallback(this));
}
public void sendResult(String result) {
UnityPlayer.UnitySendMessage("Main Camera", "message", result);
}
public void showToastTips(String tips) {
Toast.makeText(this,tips,Toast.LENGTH_LONG).show();
}
public void callQueryQQUserInfo() {
com.tencent.ysdk.api.YSDKApi.queryUserInfo(ePlatform.QQ);
}
}
最重要的一步 xml配置 一般出现问题都是应为这个没有配置好
1.
android:name=”com.ddd.ddd.UnityPlayerActivity”>
把UnityPlayerActivity该成自己方法的名字
2.按照官网上的像xml里面添加 只需要把包命、QQid、微信id都该为自己的就可以了,QQid前面有tencent
遇到的问题
1.assets 东西没有拷贝
2.ysdkconf里面的id没有修改
3.libs缺少android-support-v4
4.当修改xml里面东西时候 出现错误提示 broject->clean 一下就ok了
5. xml这个忘记添加sdk版本
6. id不对或者测试的时候未用测试账号 (测试账号在第一张图片那个界面qq登陆-》应用调试者)
7. 返回openip为1002 登陆的时候提示登陆失败,原因: id问题 ps:建议先把所有id都按照demo里的id试一下 确定不是自己应用id的问题
8.还有个支付返回1016…….坑爹那 没有接入支付,检查应用是否已申请接入支付 。。。。听客服说联调状态不算…还要提交审核才可以
9.分区配置的回调url(服务器配置 填上去就ok了 貌似最好只填一个)配置好之后 进入联调 -》发布沙盒或者正式,过一段时间后才生效
10. 如果支付可以调出 支付界面,一般来说除了支付参数外都没什么问题,支付提示系统繁忙就是回调url的问题(可以和客服要一个url进行测试使用)
11. 支付参数问题 (item 的都是供腾讯app使用 显示到支付界面上,midasExt 服务器发格式 自行配置,服务器按照这个发货)
12. 微信没有回调,文档里面很详细
文档网址
Launch Activity ,注意 :demo中是直接用SplashActivity ,我用的是MainActivity 详见配置xml 1. 中
13.sharesdk和应用宝sdk 冲突解决
14. splash screen 不适配 , 将launch 和 midas 配置 令android:screenOrientation=”landscape”>
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
YSDK 打成.jar包接入unity
创建新的android 工程, 导入 eclipse 下面的 YSDK-Eclipse 下的library 添加依赖 (一定要导入,我把YSDK_Android.jar 弄到libs 文件下了 没有导入这个不报错,但是打出包就出问题了 提示找不到libary )
下面就是assets资源,修改ysdkconf、写脚本,配置xml , 导入res资源(demo下的res资源,加上自己的游戏图标 ,我图标所在位置放在drawable下面了,在xml中修改app icon 就ok了 android:icon=”@drawable/图标名字”) 和上面接入一样步骤
launch Activity xml 根据提示修改的 其他的都复制粘贴修改id就ok了
<activity
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTop"
android:configChanges="orientation|screenSize|keyboardHidden"
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
res下的资源一定要有 libs下面就两个.jar
然后导出.jar 只选src ,和android上的 libs res assets xml一块放unity中就ok了(我新建了个bin 放bin下面了)
libs 下面的 class.jar删除了 然后导入三个文件夹 eclipse 下 libary 里的 全部copy过来报重复
把ysdk_android.jar 解压缩,assets 下面的资源放到 lassets 下面 ,
要多用真机跑,在eclipse DDMS 下面看提示,根据提示修改
如果提示bitmap的问题就是res 资源没找到 修改下 这个 或者添加res资源。(添加res资源需要重新打.jar)