本文是原生安卓SDK接入,对安卓不是很熟悉的话,可以考虑ShareSDK,直接封装好的登录分享SDK,无需在安卓层面架接,只需要在Unity里面调用相应接口即可。
1.打开腾讯开放平台
找到接入指南。
下载移动游戏的sdk
2.申请个人APP_ID.需要手持身份证 拍照认证,有点烦。
3.下载的SDK包 解压如下
有开发者文档,以及相应的jar包。
4.创建Android工程,将Unity中的Jar包 拷入到安卓工程app-->libs下。
Unity的jar的位置 在之前 unity 与安卓交互基础中 有提到,将下载的sdk 包中的libs 下面的
也一起放到安卓工程下面的libs里面,还有以下两个文件夹。
搞好之后的libs 如下:
然后设置jar依赖。
同时在unity里面 Plugins 文件夹下面 如下:
5.开始写Java 代码:
因为我们要导出jar包,所以先将app-buildgradle文件 修改一下:
这样就可以导出jar文件。
修改MainActivity 类,继承 UnityPlayerActivity。
新建一个GameHelp 类,和TencentQQ类。在onCreate函数初始化
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GameHelper.Init(this);
TencentQQ.Init(this);
}
TencentQQ类:负责QQ登陆的主要逻辑,对外开放一些接口。
public class TencentQQ {
private static Tencent m_Tencent;
private static Activity m_MainActivity;
public static String TAG="TencentQQ";
//个人申请的App_ID
private static String APP_ID="Your APP_ID";
private static BaseUiListener m_LoginCallBack=new BaseUiListener();
//初始化
public static void Init(Activity activity)
{
Log.d(TAG, "TencentQQ Init");
m_Tencent=Tencent.createInstance(APP_ID,activity.getApplicationContext());
m_MainActivity=activity;
}
//登录函数
public static void Login()
{
Log.d(TAG, "QQLogin");
m_Tencent.login(m_MainActivity,"all",m_LoginCallBack);
}
// 注销登录
public static void LogOut()
{
Log.d(TAG, "QQLogOut");
m_Tencent.logout(m_MainActivity);
}
//检测授权是否过期
public static boolean CheckAutoVaild()
{
return m_Tencent.checkSessionValid(APP_ID);
}
//刷新票据
public static JSONObject RefreshSession()
{
JSONObject jsonObject=m_Tencent.loadSession(APP_ID);
if (jsonObject==null)
{
Login();
}
else
{
m_Tencent.initSessionCache(jsonObject);
}
Log.d(TAG, "RefreshSession"+jsonObject.toString());
return SetSelfData(jsonObject);
}
//登陆成功回调
public static void LoginCallBack(final JSONObject jsonObject)
{
Log.d(TAG, "LoginCallBack: "+jsonObject.toString());
//http请求 只能运行在主线程(获取Unionid)
new Thread(new Runnable()
{
@Override
public void run()
{
initOpenidAndToken(jsonObject);
JSONObject data=SetSelfData(jsonObject);
//传输数据
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGINCALLBACK,0,0,0,
data.toString(),"","");
}
}).start();
}
//格式化成自己需要的数据
public static JSONObject SetSelfData(JSONObject data)
{
JSONObject jsonObject=new JSONObject();
try
{
String token=data.getString(Constants.PARAM_ACCESS_TOKEN);
String expires=jsonObject.getString(Constants.PARAM_EXPIRES_IN);
String openId=jsonObject.getString(Constants.PARAM_OPEN_ID);
String paytoken=data.getString("pay_token");
String pf=data.getString("pf");
String pfkey=data.getString("pfkey");
String expirestime=data.getString(Constants.PARAM_EXPIRES_TIME);
String unionid=getUnionid(token);
jsonObject.put("openid",openId);
jsonObject.put("token",token);
jsonObject.put("unionid",unionid);
jsonObject.put("refreshtoken","");
jsonObject.put("expires",expires);
jsonObject.put("paytoken",paytoken);
jsonObject.put("pf",pf);
jsonObject.put("pfkey",pfkey);
jsonObject.put("expirestime",expirestime);
}
catch (Exception e)
{
Log.e(TAG, "SetSelfData:设置统一QQ票据失败!");
}
return jsonObject;
}
//产生openid 和 Token
public static void initOpenidAndToken(JSONObject jsonObject)
{
try
{
String token=jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
String expires=jsonObject.getString(Constants.PARAM_EXPIRES_IN);
String openId=jsonObject.getString(Constants.PARAM_OPEN_ID);
if (!TextUtils.isEmpty(token)&&!TextUtils.isEmpty(expires)&&!TextUtils.isEmpty(openId))
{
m_Tencent.setAccessToken(token,expires);
m_Tencent.setOpenId(openId);
}
}
catch (Exception e)
{
}
}
//获取unionid
public static String getUnionid(String token)
{
String unionid="";
try
{
URL url=new URL("https://graph.qq.com/oauth2.0/me?access_token="+token+"&unionid=1");
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int code=connection.getResponseCode();
if(code==HttpURLConnection.HTTP_OK)
{
InputStream is =connection.getInputStream();
byte[] data=readStream(is);
String json=new String(data);
json=json.replace("(","").replace(")","").replace
("callback","");
JSONObject jsonObject=new JSONObject(json);
unionid=jsonObject.getString("unionid");
}
}
catch (Exception e)
{
Log.e(TAG, "getUnionid: 获取unionid错误:"+e.toString() );
}
return unionid;
}
//处理低端机上因内存紧张导致无回调
public static void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode==Constants.REQUEST_API)
{
if(resultCode==Constants.REQUEST_LOGIN)
{
m_Tencent.handleResultData(data,m_LoginCallBack);
}
m_Tencent.onActivityResultData(requestCode,resultCode,data,m_LoginCallBack);
}
}
实现回调:
所有的SDK接口调用,都会传入一个回调,用以接收SDK返回的调用结果。
(1) 实现回调 IUiListener
调用SDK已经封装好的接口时,例如:登录、快速支付登录、应用分享、应用邀请等接口,需传入该回调的实例。
public class BaseUiListener implements IUiListener
{
@Override
public void onComplete(Object o)
{
if (o==null)
{
return;
}
JSONObject jsonObject=(JSONObject)o;
//回调成功,但没有数据
if (jsonObject!=null&&jsonObject.length()==0)
{
return;
}
Log.d(TencentQQ.TAG, "onComplete: 登陆成功!");
TencentQQ.LoginCallBack(jsonObject);
}
@Override
public void onError(UiError uiError)
{
Log.d(TencentQQ.TAG, "onComplete: 登陆失败!");
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGIN,1,0,0
,"","","");
}
@Override
public void onCancel()
{
Log.d(TencentQQ.TAG, "onComplete: 取消登陆!");
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGIN,2,0,0
,"","","");
}
应用调用Andriod_SDK接口时,如果要成功接收到回调,需要在调用接口的Activity的onActivityResult方法中增加如下代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode,resultCode,data);
TencentQQ.onActivityResult(requestCode,resultCode,data);
}
GameHelper类,主要用于 和Unity之间相互调用传递数据
public class GameHelper
{
private static MainActivity m_Activity=null;
private static String m_PlatformObject="PlatformObject";
private static String m_MethodName="OnMessage";
public static String TAG="GameHelper";
//QQ登录回调
public final static int PLATFORM_MSG_QQLOGINCALLBACK=1;
//QQ登录
public final static int PLATFORM_MSG_QQLOGIN=1;
//QQ注销
public final static int PLATFORM_MSG_QQLOGOUT=2;
//初始化方法
public static void Init(MainActivity activity)
{
m_Activity=activity;
}
//androis端发送消息到unity
public static void SendPlatformMessageToUnity(int iMsgId,int iParam1,int iParam2,int iParam3,
String strParam1,String strParam2,String strParam3)
{
String jsonString=GetJsonStr(iMsgId, iParam1, iParam2,
iParam3, strParam1, strParam2, strParam3);
UnityPlayer.UnitySendMessage(m_PlatformObject, m_MethodName, jsonString);
}
public static void SendUnityMessageToPlatform(int iMsgId,int iParam1,int iParam2,int iParam3,int iParam4,
String strParam1,String strParam2,String strParam3,String strParam4)
{
Log.d(TAG, "SendUnityMessageToPlatform: iMsgId"+iMsgId+"iParam1"+iParam1+"iParam2"+iParam2+"iParam3"+iParam3
+"iParam4"+iParam4+"strParam1"+strParam1+"strParam2"+strParam2+"strParam3"+strParam3+"strParam4"+strParam4);
if (m_Activity==null)
{
Log.e(TAG, "m_Activity is null: ");
}
switch (iMsgId)
{
case PLATFORM_MSG_QQLOGIN:
TencentQQ.Login();
break;
case PLATFORM_MSG_QQLOGOUT:
TencentQQ.LogOut();
break;
case PLATFORM_MSG_WXLOGIN:
TencentWX.Login();
break;
case PLATFORM_MSG_WXLOGOUT:
TencentWX.LogOut();
break;
}
}
//从Android获取Str类型
public static String GetStringFromPlatform(int type)
{
switch (type)
{
case 1:
//QQ授权是否过期
return String.valueOf(TencentQQ.CheckAutoVaild());
case 2:
//刷新QQ票据
return TencentQQ.RefreshSession().toString();
case 3://WX授权是否过期
return String.valueOf(TencentWX.CheckAutorVaild());
case 4://刷新WX票据
return TencentWX.RefreshSession().toString();
}
return "";
}
//通过json对象构造字符串
public static String GetJsonStr(int iMsgId,int iParam1,int iParam2,int iParam3,
String strParam1,String strParam2,String strParam3)
{
try
{
JSONObject object =new JSONObject();
object.put("iMsgId", iMsgId);
object.put("iPararm1", iParam1);
object.put("iPararm2", iParam2);
object.put("iPararm3", iParam3);
object.put("strPararm1", strParam1);
object.put("strPararm2", strParam2);
object.put("strPararm3", strParam3);
return object.toString();
}
catch(JSONException e)
{
Log.e(TAG, "Json Error: "+e.toString() );
return "";
}
}
之后就可以导出Jar包,放入Unity下Android文件夹下,注意导出的时候,删掉Jar包中导入的Unity 的Jar,不然后面打包可能会报错。
配置AndroidManifest文件:
添加 <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>,并且去掉 application 中的一些属性,仅留下 android:label="@string/app_name"
在应用的AndroidManifest.xml增加配置的<application>节点下增加以下配置(注:不配置将会导致无法调用API)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
新增activity
<activity android:name="com.tencent.tauth.AuthActivity" android:noHistory="true" android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="Your APP_ID" />
</intent-filter>
</activity>
还有文档中没有写到
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden">
</activity>
通过以上步骤,工程就已经配置完成了。我们就可以在Unity工程中 去调用GameHelper中的接口了。
我这边 打包的时候 因为 有QQ 和WX 登录 的jar,打包时报错
仔细看错误信息,会发现 存在不止一个BuildConfig 文件,将 导出的jar包 用解压软件 打开(不是解压),
删掉那个文件,再次打包就没有报错了。APP_ID 换成自己的。微信的接入,按照文档,手法都是差不多的。