SDK准备
微信Android接入指南:
接入指南 / Android接入指南 (qq.com)
首先在Android Studio的build.gradle里面添加:
1 2 3
| dependencies { implementation 'com.tencent.mm.opensdk:wechat-sdk-android:+' }
|
等待Android Studio出现的提示并点击“sync now”,等待gradle自动添加完成依赖。
下载的jar包位置:在Project资源管理模式下——点击External Libraries——找到Gradle: com.tencent.mm.opensdk:wechat-sdk-android
——classes.jar。选中classes.jar——右键Open In——Explorer,将文件夹内的jar包复制粘贴到Unity的Assets——Plugins——Android——libs文件夹下,注意将此jar包的名称修改为wechat-sdk-android
TencentWX类
在之前的文件夹内新建TencentWX
类,提供的方法内容基本上和TenecntQQ类相同,但是具体细节上有所不同:
GetAccessToken
方法类似于TencentQQ.LoginCallBack
方法,但是微信这个回调需要我们发送https请求来获取用户信息,而不是直接返回。注意,微信的回调方法和QQ的都需要开启一个新线程,因为这两个地方都需要在安卓底层发送http请求。而微信下面介绍的方法也是发送http请求,但是不需要开启新线程,因为它们不是安卓底层调用的,而是Unity需要调用的,会自动在新线程中请求。
使用SaveRefreshToken
和GetRefreshToken
来保存和获取refreshtoken,这个token就是用来缓存用户信息的,QQ提供了缓存token的API,而微信没有,所以我们这里需要自己写保存和读取的方法。微信每次使用https登录请求都会获得两个token,一个是accesstoken,一个是refreshtoken,前者只有2小时有效时间,所以我们只保存后者。
使用CheckAuthorValid
方法检查refreshtoken票据,和QQ也不一样,QQ已经封装好了一个方法,而微信需要自己发起一个获取token的http请求,得到新的accesstoken
使用RefreshSession
方法刷新accesstoken,也是发起一次获取token的http请求。
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 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
| package com.DefaultCompany.ResLoadPrg;
import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.util.Log;
import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import org.json.JSONObject;
import java.io.InputStream; import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class TencentWX { public static IWXAPI WXapi; private static Activity m_MainActivity; private static final String TAG = "TencentWX"; private static final String APP_ID = "wxfin458bf9gt"; private static final String APP_Secret = "jncnignaondh364b58EW7ng84hag";
public static void Init(Activity activity){ Log.i(TAG, "Init: "); m_MainActivity = activity; WXapi = WXAPIFactory.createWXAPI(activity,APP_ID,true); WXapi.registerApp(APP_ID); }
public static void Login(){ Log.i(TAG, "WXLogin"); SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "resloadprg_wx_test"; WXapi.sendReq(req); }
public static void Logout(){ Log.i(TAG,"WXLogout"); WXapi.unregisterApp(); }
public static boolean CheckAuthorValid(){ try { String refreshToken = GetRefreshToken(); if(refreshToken == null || refreshToken.equals("")){ return false; } URL url = new URL("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid="+APP_ID+ "&grant_type=refresh_token&refresh_token=" + refreshToken); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000);
int code = connection.getResponseCode(); if(code == HttpsURLConnection.HTTP_OK){ InputStream is = connection.getInputStream(); byte[] data = TencentQQ.ReadStream(is); String json = new String(data); JSONObject jsonObject = new JSONObject(json); if(jsonObject.has("errcode")){ Log.e(TAG, "CheckAuthorValid: 授权无效,需要重新授权"); return false; } else { Log.i(TAG, "CheckAuthorValid: 授权有效,不需要再授权"); return true; } } } catch (Exception e){ Log.e(TAG, "CheckAuthorValid: 检测是否授权错误!" + e.toString()); } return false; }
public static JSONObject RefreshSession(){ try{ String refreshToken = GetRefreshToken(); if(refreshToken == null || refreshToken.equals("")){ return null; } URL url = new URL("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid="+APP_ID+ "&grant_type=refresh_token&refresh_token=" + refreshToken); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000);
int code = connection.getResponseCode(); if(code == HttpsURLConnection.HTTP_OK){ InputStream is = connection.getInputStream(); byte[] data = TencentQQ.ReadStream(is); String json = new String(data); JSONObject jsonObject = new JSONObject(json); if(!jsonObject.has("errcode")){ return SetSelfData(jsonObject); } } } catch (Exception e){ Log.e(TAG, "RefreshSession: 刷新票据错误:" + e.toString()); } return null; }
private static void SaveRefreshToken(String token){ SharedPreferences sharedPreferences = m_MainActivity.getSharedPreferences("Wxcache", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("refreshtoken",token); editor.apply(); }
private static String GetRefreshToken(){ SharedPreferences sharedPreferences = m_MainActivity.getSharedPreferences("Wxcache",Context.MODE_PRIVATE); return sharedPreferences.getString("refreshtoken",""); }
public static void GetAccessToken(final String wxcode){ new Thread(new Runnable() { @Override public void run() { try{ URL url = new URL("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APP_ID + "&secret=" + APP_Secret + "&code=" + wxcode + "&grant_type=authorization_code"); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000);
int code = connection.getResponseCode(); if(code == HttpsURLConnection.HTTP_OK){ InputStream is = connection.getInputStream(); byte[] data = TencentQQ.ReadStream(is); String json = new String(data); JSONObject jsonObject = new JSONObject(json); JSONObject jsonData = SetSelfData(jsonObject); GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_WXLOGINCALLBACK,0,0,0,jsonData.toString(),"",""); } } catch (Exception e){ Log.e(TAG, "GetAccessToken: 获取登录票据错误"+e.toString()); } } }).start(); }
private static JSONObject SetSelfData(JSONObject data){ JSONObject jsonObject = new JSONObject(); try { String token = data.getString("access_token"); String expires = data.getString("expires_in"); String openid = data.getString("openid"); String refreshtoken = data.getString("refresh_token"); String expirestime = data.getString("expires_in"); String unionid = GetUnionId(token,openid);
jsonObject.put("openid",openid); jsonObject.put("token",token); jsonObject.put("unionid",unionid); jsonObject.put("refreshtoken",refreshtoken); jsonObject.put("expires",expires); jsonObject.put("paytoken",""); jsonObject.put("pf",""); jsonObject.put("pfkey",""); jsonObject.put("expirestime",expirestime); SaveRefreshToken(refreshtoken); } catch (Exception e){ Log.e(TAG, "SetSelfData: 设微信统一票据失败" + e.toString() ); } return jsonObject; }
private static String GetUnionId(String token,String openid){ String unionId = ""; try{ URL url = new URL("https://api.weixin.qq.com/sns/userinfo?access_token="+token+"&openid=:" + openid); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000);
int code = connection.getResponseCode(); if(code == HttpsURLConnection.HTTP_OK){ InputStream is = connection.getInputStream(); byte[] data = TencentQQ.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: 失败!" + e.toString() ); } return unionId; } }
|
注意将此类在MainActivity
中初始化
在GameHelper
中调用Tencent的Login
、Logout
和CheckAuthorValid
、RefreshSession
方法
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
| public static final int PLATFORM_MSG_QQLOGIN = 1; public static final int PLATFORM_MSG_QQLOGOUT = 2; public static final int PLATFORM_MSG_WXLOGIN = 3; public static final int PLATFORM_MSG_WXLOGOUT = 4; public static void SendUnityMessageToPlatform( int iMsgId, int iParam1, int iParam2, int iParam3, int iParam4, String strParam1, String strParam2, String strParam3, String strParam4 ){ 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; } } public static final int PLATFORM_MSG_QQ_AUTHORVALID = 1; public static final int PLATFORM_MSG_QQ_REFRESHSESSION = 2;
public static final int PLATFORM_MSG_WX_AUTHORVALID = 3; public static final int PLATFORM_MSG_WX_REFRESHSESSION = 4; public static String GetStringFromPlatform(int type){ switch (type){ case PLATFORM_MSG_QQ_AUTHORVALID: return String.valueOf(TencentQQ.CheckAuthorValid()); case PLATFORM_MSG_QQ_REFRESHSESSION: return TencentQQ.RefreshSession().toString(); case PLATFORM_MSG_WX_AUTHORVALID: return String.valueOf(TencentWX.CheckAuthorValid()); case PLATFORM_MSG_WX_REFRESHSESSION: return TencentWX.RefreshSession().toString(); } return ""; }
|
WXAPI
在com.DefaultCompany.ResLoadPrg
文件夹内新建wxapi文件夹(如果不能在Android Studio内新建就在Windows资源管理器内新建)。
在这个文件夹内新建几个类
WXEntryActivity
这个类相当于QQ接入时的BaseUiListener
,用来获取回调,和QQ不同的是,微信获取回调的这个类必须属于Activity
子类。
还有和QQ不同的是,在QQ中的回调会直接传回包含用户信息的json。而微信在登录回调成功后需要再次发送Https请求来得到用户信息。
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
| package com.DefaultCompany.ResLoadPrg.wxapi;
import android.app.Activity; import android.os.Bundle; import android.util.Log;
import com.DefaultCompany.ResLoadPrg.GameHelper; import com.DefaultCompany.ResLoadPrg.TencentWX; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private static final String TAG = WXEntryActivity.class.getName();
@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); TencentWX.WXapi.handleIntent(getIntent(),this); }
@Override public void onReq(BaseReq baseReq) {
}
@Override public void onResp(BaseResp baseResp) {
int type = baseResp.getType();
switch (baseResp.errCode){ case BaseResp.ErrCode.ERR_AUTH_DENIED: Log.d(TAG, "onResp: 拒绝微信授权登录"); GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_WXLOGINCALLBACK,1,0,0,"","",""); break; case BaseResp.ErrCode.ERR_USER_CANCEL: Log.d(TAG, "onResp: 用户取消登录"); GameHelper.SendPlatformMessageToUnity(GameHelper.PLATFORM_MSG_WXLOGINCALLBACK,2,0,0,"","",""); break; case BaseResp.ErrCode.ERR_OK: if(type == 1){ String code = ((SendAuth.Resp)baseResp).code; Log.d(TAG,"onResp: 微信登录成功"); TencentWX.GetAccessToken(code); } else if(type == 2){ Log.i(TAG, "onResp: 微信分享成功"); } break; } } }
|