


Detailed graphic and text explanation of the steps for integrating WeChat login on Android
Mar 15, 2017 pm 05:23 PMThis article will give you a detailed explanation with pictures and textAndroidThe steps to integrate WeChat login. Through the content compiled in the article, you only need a few lines of code to realize the WeChat login function. Friends who are just interested Let’s take a look below.
1. First write in onCreate of Application:
// GeneralAppliction.java public static IWXAPI sApi; @Override public void onCreate() { super.onCreate(); sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID); }
2. Add where you need to log in:
// MainActivity.java WXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);
3 ,The specific integration steps are described in detail below.
Integration steps:
1. Register and create an application on the open platform and apply for login permission
2. Download sdk, Copy related files to the project directory
3. Globally initialize the WeChat component
4. Request authorization to log in and obtain the code
5. Obtain through code Authorization password access_token
6. In step 5, determine whether access_token exists and expires
7. If access_token expires and is invalid, use refresh_token to refresh
8. Use access_token to obtain User information
1. Register and create an application on the open platform and apply for login permission
This step does not need to be explained. The only way is to register an account on the WeChat open platform. Then create the mobile app.
What needs to be noted is: the application signature part
I use the online signature here key'smd5, for this issue that needs attention, you can see: Android signature summary
2. Download the sdk and copy the relevant files to the project directory
Download of development tool kit (SDK): libraries and files required for WeChat sharing, login, collection, payment and other functions
Example Demo
After downloading, copy the libammsdk.jar file to the libs directory of the AS project, and copy the entire wxapi directory under the source file directory in the example Demo to the root package under the src of the project directory:
If the wxapi folder is placed in the wrong location, you will not be able to log in, and the WeChat sdk cannot find the login Activity authorization function. Then add in Manifest.xml:
<activity android:name=".wxapi.WXEntryActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:configChanges="keyboardHidden|orientation|screenSize" android:exported="true" android:screenOrientation="portrait" />
3. Globally initialize the WeChat component
Globally initialize the WeChat component, of course, in the onCreate of the Application (of course, the onCreate of the Activity is also possible, in order to use the WeChat api globallyObject to facilitate operation):
@Override public void onCreate() { super.onCreate(); // 初始化微信組件 initWeiXin(); } public static IWXAPI sApi; private void initWeiXin() { sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID); }
4. Request authorization to log in and get the code
For the single principle of the same business, I related WeChat All are packaged into the wxapi package and WXEntryActivity:
// 實(shí)現(xiàn)IWXAPIEventHandler 接口,以便于微信事件處理的回調(diào) public class WXEntryActivity extends Activity implements IWXAPIEventHandler { private static final String WEIXIN_ACCESS_TOKEN_KEY = "wx_access_token_key"; private static final String WEIXIN_OPENID_KEY = "wx_openid_key"; private static final String WEIXIN_REFRESH_TOKEN_KEY = "wx_refresh_token_key"; private Gson mGson; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 微信事件回調(diào)接口注冊(cè) GeneralAppliction.sApi.handleIntent(getIntent(), this); mGson = new Gson(); } /** * 微信組件注冊(cè)初始化 * @param context 上下文 * @param weixin_app_id appid * @return 微信組件api對(duì)象 * / public static IWXAPI initWeiXin(Context context, @NonNull String weixin_app_id) { if (TextUtils.isEmpty(weixin_app_id)) { Toast.makeText(context.getApplicationContext(), "app_id 不能為空", Toast.LENGTH_SHORT).show(); } IWXAPI api = WXAPIFactory.createWXAPI(context, weixin_app_id, true); api.registerApp(weixin_app_id); return api; } /** * 登錄微信 * * @param api 微信服務(wù)api */ public static void loginWeixin(Context context, IWXAPI api) { // 判斷是否安裝了微信客戶端 if (!api.isWXAppInstalled()) { Toast.makeText(context.getApplicationContext(), "您還未安裝微信客戶端!", Toast.LENGTH_SHORT).show(); return; } // 發(fā)送授權(quán)登錄信息,來獲取code SendAuth.Req req = new SendAuth.Req(); // 應(yīng)用的作用域,獲取個(gè)人信息 req.scope = "snsapi_userinfo"; /** * 用于保持請(qǐng)求和回調(diào)的狀態(tài),授權(quán)請(qǐng)求后原樣帶回給第三方 * 為了防止csrf攻擊(跨站請(qǐng)求偽造攻擊),后期改為隨機(jī)數(shù)加session來校驗(yàn) */ req.state = "app_wechat"; api.sendReq(req); } // 微信發(fā)送請(qǐng)求到第三方應(yīng)用時(shí),會(huì)回調(diào)到該方法 @Override public void onReq(BaseReq req) { switch (req.getType()) { case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX: break; case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX: break; default: break; } } // 第三方應(yīng)用發(fā)送到微信的請(qǐng)求處理后的響應(yīng)結(jié)果,會(huì)回調(diào)到該方法 @Override public void onResp(BaseResp resp) { switch (resp.errCode) { // 發(fā)送成功 case BaseResp.ErrCode.ERR_OK: // 獲取code String code = ((SendAuth.Resp) resp).code; // 通過code獲取授權(quán)口令access_token getAccessToken(code); break; } } }
If you have any questions about what the code is:
The third party needs to use the code to obtain the access_token. The timeout of the code is 10 minutes. A code can only be successfully exchanged for the access_token once and then it will become invalid. The temporary and one-time nature of the code ensures the security of WeChat authorized login. Third parties can further enhance the security of their own authorized logins by using https and state parameters.
In this way, where the client uses only needs to be:
WXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);
5. Obtain through code Authorization password access_token
We obtained the code in the onResp callback method, and then obtained the authorization password access_token through the code:
/** * 獲取授權(quán)口令 */ private void getAccessToken(String code) { String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid=" + AppConst.WEIXIN_APP_ID + "&secret=" + AppConst.WEIXIN_APP_SECRET + "&code=" + code + "&grant_type=authorization_code"; // 網(wǎng)絡(luò)請(qǐng)求獲取access_token httpRequest(url, new ApiCallback<String>() { @Override public void onSuccess(String response) { Logger.e(response); // 判斷是否獲取成功,成功則去獲取用戶信息,否則提示失敗 processGetAccessTokenResult(response); } @Override public void onError(int errorCode, final String errorMsg) { Logger.e(errorMsg); showMessage("錯(cuò)誤信息: " + errorMsg); } @Override public void onFailure(IOException e) { Logger.e(e.getMessage()); showMessage("登錄失敗"); } }); } /** * 處理獲取的授權(quán)信息結(jié)果 * @param response 授權(quán)信息結(jié)果 */ private void processGetAccessTokenResult(String response) { // 驗(yàn)證獲取授權(quán)口令返回的信息是否成功 if (validateSuccess(response)) { // 使用Gson解析返回的授權(quán)口令信息 WXAccessTokenInfo tokenInfo = mGson.fromJson(response, WXAccessTokenInfo.class); Logger.e(tokenInfo.toString()); // 保存信息到手機(jī)本地 saveAccessInfotoLocation(tokenInfo); // 獲取用戶信息 getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid()); } else { // 授權(quán)口令獲取失敗,解析返回錯(cuò)誤信息 WXErrorInfo wxErrorInfo = mGson.fromJson(response, WXErrorInfo.class); Logger.e(wxErrorInfo.toString()); // 提示錯(cuò)誤信息 showMessage("錯(cuò)誤信息: " + wxErrorInfo.getErrmsg()); } } /** * 驗(yàn)證是否成功 * * @param response 返回消息 * @return 是否成功 */ private boolean validateSuccess(String response) { String errFlag = "errmsg"; return (errFlag.contains(response) && !"ok".equals(response)) || (!"errcode".contains(response) && !errFlag.contains(response)); }
6. Determine whether access_token exists and expires in step 5
在回調(diào)的onResp方法中獲取code后,處理access_token是否登錄過或者過期的問題:
// 從手機(jī)本地獲取存儲(chǔ)的授權(quán)口令信息,判斷是否存在access_token,不存在請(qǐng)求獲取,存在就判斷是否過期 String accessToken = (String) ShareUtils.getValue(this, WEIXIN_ACCESS_TOKEN_KEY, "none"); String openid = (String) ShareUtils.getValue(this, WEIXIN_OPENID_KEY, ""); if (!"none".equals(accessToken)) { // 有access_token,判斷是否過期有效 isExpireAccessToken(accessToken, openid); } else { // 沒有access_token getAccessToken(code); }
判斷授權(quán)口令是否有效:
/** * 判斷accesstoken是過期 * @param accessToken token * @param openid 授權(quán)用戶唯一標(biāo)識(shí) */ private void isExpireAccessToken(final String accessToken, final String openid) { String url = "https://api.weixin.qq.com/sns/auth?" + "access_token=" + accessToken + "&openid=" + openid; httpRequest(url, new ApiCallback<String>() { @Override public void onSuccess(String response) { Logger.e(response); if (validateSuccess(response)) { // accessToken沒有過期,獲取用戶信息 getUserInfo(accessToken, openid); } else { // 過期了,使用refresh_token來刷新accesstoken refreshAccessToken(); } } @Override public void onError(int errorCode, final String errorMsg) { Logger.e(errorMsg); showMessage("錯(cuò)誤信息: " + errorMsg); } @Override public void onFailure(IOException e) { Logger.e(e.getMessage()); showMessage("登錄失敗"); } }); }
7. 如果access_token過期無效,就用refresh_token來刷新
/** * 刷新獲取新的access_token * / private void refreshAccessToken() { // 從本地獲取以存儲(chǔ)的refresh_token final String refreshToken = (String) ShareUtils.getValue(this, WEIXIN_REFRESH_TOKEN_KEY, ""); if (TextUtils.isEmpty(refreshToken)) { return; } // 拼裝刷新access_token的url請(qǐng)求地址 String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?" + "appid=" + AppConst.WEIXIN_APP_ID + "&grant_type=refresh_token" + "&refresh_token=" + refreshToken; // 請(qǐng)求執(zhí)行 httpRequest(url, new ApiCallback<String>() { @Override public void onSuccess(String response) { Logger.e("refreshAccessToken: " + response); // 判斷是否獲取成功,成功則去獲取用戶信息,否則提示失敗 processGetAccessTokenResult(response); } @Override public void onError(int errorCode, final String errorMsg) { Logger.e(errorMsg); showMessage("錯(cuò)誤信息: " + errorMsg); // 重新請(qǐng)求授權(quán) loginWeixin(WXEntryActivity.this.getApplicationContext(), GeneralAppliction.sApi); } @Override public void onFailure(IOException e) { Logger.e(e.getMessage()); showMessage("登錄失敗"); // 重新請(qǐng)求授權(quán) loginWeixin(WXEntryActivity.this.getApplicationContext(), GeneralAppliction.sApi); } }); }
8. 使用access_token獲取用戶信息
/** * 獲取用戶信息 * / private void getUserInfo(String access_token, String openid) { String url = "https://api.weixin.qq.com/sns/userinfo?" + "access_token=" + access_token + "&openid=" + openid; httpRequest(url, new ApiCallback<String>() { @Override public void onSuccess(String response) { // 解析獲取的用戶信息 WXUserInfo userInfo = mGson.fromJson(response, WXUserInfo.class); Logger.e("用戶信息獲取結(jié)果:" + userInfo.toString()); } @Override public void onError(int errorCode, String errorMsg) { showMessage("錯(cuò)誤信息: " + errorMsg); } @Override public void onFailure(IOException e) { showMessage("獲取用戶信息失敗"); } }); }
通信部分
private OkHttpClient mHttpClient = new OkHttpClient.Builder().build(); private Handler mCallbackHandler = new Handler(Looper.getMainLooper()); /** * 通過Okhttp與微信通信 * * @param url 請(qǐng)求地址 * @throws Exception */ public void httpRequest(String url, final ApiCallback<String> callback) { Logger.e("url: %s", url); final Request request = new Request.Builder() .url(url) .get() .build(); mHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, final IOException e) { if (callback != null) { mCallbackHandler.post(new Runnable() { @Override public void run() { // 請(qǐng)求失敗,主線程回調(diào) callback.onFailure(e); } }); } } @Override public void onResponse(Call call, final Response response) throws IOException { if (callback != null) { if (!response.isSuccessful()) { mCallbackHandler.post(new Runnable() { @Override public void run() { // 請(qǐng)求出錯(cuò),主線程回調(diào) callback.onError(response.code(), response.message()); } }); } else { mCallbackHandler.post(new Runnable() { @Override public void run() { try { // 請(qǐng)求成功,主線程返回請(qǐng)求結(jié)果 callback.onSuccess(response.body().string()); } catch (final IOException e) { // 異常出錯(cuò),主線程回調(diào) mCallbackHandler.post(new Runnable() { @Override public void run() { callback.onFailure(e); } }); } } }); } } } }); } // Api通信回調(diào)接口 public interface ApiCallback<T> { /** * 請(qǐng)求成功 * * @param response 返回結(jié)果 */ void onSuccess(T response); /** * 請(qǐng)求出錯(cuò) * * @param errorCode 錯(cuò)誤碼 * @param errorMsg 錯(cuò)誤信息 */ void onError(int errorCode, String errorMsg); /** * 請(qǐng)求失敗 */ void onFailure(IOException e); }
總結(jié)
集成的詳細(xì)描述就這樣,至于獲取的用戶信息,小伙伴們應(yīng)該知道后續(xù)自己業(yè)務(wù)的需求,該怎么處理了。以上就是本文的全部?jī)?nèi)容了,希望能對(duì)大家的學(xué)習(xí)或者工作帶來一定的幫助,如果有疑問大家可以留言交流。
The above is the detailed content of Detailed graphic and text explanation of the steps for integrating WeChat login on Android. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)