SDK设置

SDK下载 — QQ互联WIKI

下载里面的Android_SDK,并且解压,将解压出来的E:\EdgeDownload\opensdk_3514_lite_2023-01-13\libs\open_sdk_3.5.14.3_rc26220c_lite.jar复制粘贴到Android Studio工程的app——libs文件夹内,然后像我们引入Unity的jar包一样设置一下依赖。

同时在Unity的工程里面,新建Assets——Plugins——Android文件夹,在其内部新建libs和res文件夹,将open_sdk_3.5.14.3_rc26220c_lite.jar也复制粘贴到libs文件夹内。

TencentQQ

com.DefaultCompany.ResLoadPrg文件夹下新建TencentQQ文件

  1. 登录,调用Tencent.login方法,并在方法参数中传入下面的BaseUiListener回调类。由Unity调用

  2. 注销,调用Tencent.logout方法。由Unity调用

  3. 登录之后的回调LoginCallBack,由BaseUiListener调用,传进来一个json参数,里面包含了用户信息。同时我们还要在LoginCallBack开启一个新的线程,这是因为SetSelfData方法会发送https请求来获取unionid,安卓网络请求必须在其他线程完成。

  4. InitOpenidAndToken方法,用于处理回调来的json。使用Tencent.setAccessTokenTencent.setOpenId来保存个人信息到本地。

每个QQ用户授权登录后,会返回一个json,其中包含了openid(用户标识)、access token(QQ登录期限凭证,过期后要重新授权)、pay token(QQ支付凭证数据)

开发者使用openid获取用户的基本信息,除了OpenId,QQ还提供了UnionID,这样如果开发者有多个移动应用和网站应用连接到QQ,可以使用UnionID来取得用户唯一的标识。

  1. SetSelfData方法,用于将回调来的json格式化为另一种json,这样格式化出来的json用来和Unity通信。

  2. GetUnionId方法,通过Java发送https请求来获取用户的unionid。

  3. ReadStream方法,读取服务器传回来的流,转化为byte数组。

  4. CheckAuthorValid方法,检查登录是否有效,有效就不用重复授权登录了。这个方法由Unity调用

  5. RefreshSession方法,刷新票据,如果CheckAuthorValid方法返回的是true,那么就通过此方法返回给unity用户的登录数据。由Unity调用

防止低端机登录后无回调,调用Tencent.onActivityResultData并在MainActivity重载此方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package com.DefaultCompany.ResLoadPrg;

import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import com.tencent.tauth.Tencent;
import com.tencent.connect.common.Constants;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class TencentQQ {
private static Tencent m_Tencent;

private static Activity m_MainActivity = null;
public static final String TAG = TencentQQ.class.getName();
//开发者申请的APPID
private static final String APP_ID = "1065732495";
private static final BaseUiListener m_LoginCallback = new BaseUiListener();
public static void Init(Activity activity){
Log.i(TAG, "Init: TencentQQ");
m_MainActivity = activity;

m_Tencent = Tencent.createInstance(APP_ID,activity.getApplicationContext());
}

/**
* 处理低端机内存紧张可能导致无回调
*/
public static void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == Constants.REQUEST_API){
if(resultCode == Constants.REQUEST_LOGIN){
Tencent.handleResultData(data,m_LoginCallback);
}
Tencent.onActivityResultData(requestCode,resultCode,data,m_LoginCallback);
}
}

/**
* 登录函数
*/
public static void Login(){
Log.i(TAG, "Login: QQLogin");
m_Tencent.login(m_MainActivity,"all",m_LoginCallback);
}

/**
* 注销函数
*/
public static void Logout(){
Log.i(TAG, "Logoff: QQLogout");
m_Tencent.logout(m_MainActivity);
}

/**
* 检测授权是否过期
* @return 授权是否过期
*/
public static boolean CheckAuthorValid(){
return m_Tencent.isSessionValid();
}

/**
* 刷新票据
* @return 缓存的用户信息(已格式化)
*/
public static JSONObject RefreshSession(){
JSONObject jsonObject = m_Tencent.loadSession(APP_ID);
if(jsonObject == null){
Login();
Log.i(TAG, "RefreshSession: 没有返回票据");
}
else {
m_Tencent.initSessionCache(jsonObject);
Log.i(TAG, "RefreshSession: " + jsonObject);
}

return SetSelfData(jsonObject);
}

/**
* 登录成功回调
* @param jsonObject 从BaseUiListener传回来的信息
*/
public static void LoginCallBack(final JSONObject jsonObject){
Log.i(TAG, "LoginCallBack: " + jsonObject.toString());
new Thread(new Runnable() {
@Override
public void run() {
InitOpenidAndToken(jsonObject);
JSONObject data = SetSelfData(jsonObject);
//从安卓传给Unity时,字符串必须为"",不能为null
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGINCALLBACK,0,0,0,data.toString(),"","");
}
}).start();


}

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.OPENID);

if(!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires) && !TextUtils.isEmpty(openid)){
//下面这两步是腾讯自带的将token加密保存到本地的方法,下次登录自动引用。
m_Tencent.setAccessToken(token,expires);
m_Tencent.setOpenId(openid);
}

}
catch (Exception e){
Log.e(TAG, "InitOpenidAndToken: " + e.toString() );

}
}

/**
* 格式化为和Unity通信的Json
* @param data 源Json
* @return 格式化后的Json
*/
public static JSONObject SetSelfData(JSONObject data){
JSONObject jsonObject = new JSONObject();
try{
String token = data.getString(Constants.PARAM_ACCESS_TOKEN);
String expires = data.getString(Constants.PARAM_EXPIRES_IN);//有效期开始时间
String openid = data.getString(Constants.OPENID);
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;
}

/**
* 获取QQ的unionId
* @param token QQ用户的token
* @return 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");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();//打开连接
connection.setRequestMethod("GET");//打开连接之后,使用GET头来获取
connection.setConnectTimeout(5000);//设置链接请求延时
connection.setReadTimeout(5000);//设置获取数据延时

int code = connection.getResponseCode();
if(code == HttpsURLConnection.HTTP_OK){
InputStream is = connection.getInputStream();//获取流
byte[] data = ReadStream(is);
String json = new String(data);//通过byte创建字符串
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 byte[] ReadStream(InputStream inputStream) throws Exception{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1){
bout.write(buffer,0,len);
}
bout.close();
inputStream.close();
return bout.toByteArray();
}
}

BaseUiListener

com.DefaultCompany.ResLoadPrg文件夹下新建BaseUiListener文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.DefaultCompany.ResLoadPrg;

import android.util.Log;

import com.tencent.tauth.IUiListener;
import com.tencent.tauth.UiError;

import org.json.JSONObject;

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, "onError: 登录错误");
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGINCALLBACK,1,0,0,"","","");
}

@Override
public void onCancel() {
Log.d(TencentQQ.TAG, "onCancel: 取消登录");
GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_QQLOGINCALLBACK,2,0,0,"","","");
}

@Override
public void onWarning(int i) {

}
}

MainActivity

修改MainActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.DefaultCompany.ResLoadPrg;

import android.content.Intent;
import android.os.Bundle;
import com.unity3d.player.*;

public class MainActivity extends UnityPlayerActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GameHelper.Init(this);
TencentQQ.Init(this);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode,resultCode,data);
TencentQQ.onActivityResult(requestCode,resultCode,data);
}
}