国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android集成微信登錄的步驟詳解

2019-12-12 05:08:52
字體:
來源:轉載
供稿:網友

一、首先在Application的onCreate中寫:

// GeneralAppliction.javapublic static IWXAPI sApi;@Overridepublic void onCreate() { super.onCreate(); sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID);}

二、在需要登錄的地方添加:

// MainActivity.javaWXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);

三、下面對具體的集成步驟做詳細的描述。

集成步驟:

     1、在開放平臺注冊創建應用,申請登錄權限

     2、下載sdk,拷貝相關文件到項目工程目錄

     3、全局初始化微信組件

     4、請求授權登錄,獲取code

     5、通過code獲取授權口令access_token

     6、在第5步判斷access_token是否存在和過期

     7、如果access_token過期無效,就用refresh_token來刷新

     8、使用access_token獲取用戶信息

1. 在開放平臺注冊創建應用,申請登錄權限

這一步其實不用怎么講,無法就是在微信開放平臺上注冊一個賬號,然后創建移動應用。

需要注意的是:應用簽名的部分

此處應用簽名我使用的是線上的key的md5,關于這個需要注意的問題可以看:Android的簽名總結

2. 下載sdk,拷貝相關文件到項目工程目錄

開發工具包(SDK)的下載:可以使用微信分享、登錄、收藏、支付等功能需要的庫以及文件

示例Demo

下載后把libammsdk.jar文件拷貝到AS工程的libs目錄,并把示例Demo里源文件目錄下的wxapi目錄整個拷貝到,工程目錄的src下的根包下:

如果wxapi這個文件夾放的位置不對,講無法登錄,微信sdk無法找到登錄的Activity授權功能。然后在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. 全局初始化微信組件

全局初始化微信組件,當然是Application的onCreate里(當然Activity的onCreate也是可以的,為了全局使用微信api對象方便操作):

@Overridepublic void onCreate() {  super.onCreate(); // 初始化微信組件 initWeiXin();}public static IWXAPI sApi;private void initWeiXin() { sApi = WXEntryActivity.initWeiXin(this, AppConst.WEIXIN_APP_ID);}

4. 請求授權登錄,獲取code

為了同一業務的單一原則我把微信相關的都統一封裝到了wxapi包下和WXEntryActivity中:

// 實現IWXAPIEventHandler 接口,以便于微信事件處理的回調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); // 微信事件回調接口注冊 GeneralAppliction.sApi.handleIntent(getIntent(), this); mGson = new Gson(); } /** * 微信組件注冊初始化 * @param context 上下文 * @param weixin_app_id appid * @return 微信組件api對象 * / 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 微信服務api  */ public static void loginWeixin(Context context, IWXAPI api) { // 判斷是否安裝了微信客戶端  if (!api.isWXAppInstalled()) {  Toast.makeText(context.getApplicationContext(), "您還未安裝微信客戶端!", Toast.LENGTH_SHORT).show();  return;  } // 發送授權登錄信息,來獲取code SendAuth.Req req = new SendAuth.Req();  // 應用的作用域,獲取個人信息 req.scope = "snsapi_userinfo";  /**  * 用于保持請求和回調的狀態,授權請求后原樣帶回給第三方 * 為了防止csrf攻擊(跨站請求偽造攻擊),后期改為隨機數加session來校驗  */  req.state = "app_wechat"; api.sendReq(req); } // 微信發送請求到第三方應用時,會回調到該方法 @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;  } } // 第三方應用發送到微信的請求處理后的響應結果,會回調到該方法 @Override public void onResp(BaseResp resp) { switch (resp.errCode) {  // 發送成功  case BaseResp.ErrCode.ERR_OK: // 獲取code String code = ((SendAuth.Resp) resp).code; // 通過code獲取授權口令access_token getAccessToken(code); break; } }}

小伙伴有疑問code是啥玩意:

第三方通過code進行獲取access_token的時候需要用到,code的超時時間為10分鐘,一個code只能成功換取一次access_token即失效。code的臨時性和一次保障了微信授權登錄的安全性。第三方可通過使用https和state參數,進一步加強自身授權登錄的安全性。

這樣客戶端使用的地方只要:

WXEntryActivity.loginWeixin(MainActivity.this, GeneralAppliction.sApi);

5. 通過code獲取授權口令access_token

我們在onResp的回調方法中獲取了code,然后通過code獲取授權口令access_token:

/** * 獲取授權口令 */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";  // 網絡請求獲取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("錯誤信息: " + errorMsg);  }  @Override  public void onFailure(IOException e) { Logger.e(e.getMessage());  showMessage("登錄失敗");  }  });}/** * 處理獲取的授權信息結果 * @param response 授權信息結果 */private void processGetAccessTokenResult(String response) {  // 驗證獲取授權口令返回的信息是否成功 if (validateSuccess(response)) { // 使用Gson解析返回的授權口令信息  WXAccessTokenInfo tokenInfo = mGson.fromJson(response, WXAccessTokenInfo.class); Logger.e(tokenInfo.toString()); // 保存信息到手機本地 saveAccessInfotoLocation(tokenInfo); // 獲取用戶信息  getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid());  } else { // 授權口令獲取失敗,解析返回錯誤信息  WXErrorInfo wxErrorInfo = mGson.fromJson(response, WXErrorInfo.class);  Logger.e(wxErrorInfo.toString());  // 提示錯誤信息 showMessage("錯誤信息: " + wxErrorInfo.getErrmsg());  }}/** * 驗證是否成功 * * @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. 在第5步判斷access_token是否存在和過期

在回調的onResp方法中獲取code后,處理access_token是否登錄過或者過期的問題:

// 從手機本地獲取存儲的授權口令信息,判斷是否存在access_token,不存在請求獲取,存在就判斷是否過期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);}

判斷授權口令是否有效:

/** * 判斷accesstoken是過期 * @param accessToken token * @param openid 授權用戶唯一標識 */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("錯誤信息: " + errorMsg); } @Override public void onFailure(IOException e) { Logger.e(e.getMessage()); showMessage("登錄失敗"); } });}

7. 如果access_token過期無效,就用refresh_token來刷新

/** * 刷新獲取新的access_token */private void refreshAccessToken() { // 從本地獲取以存儲的refresh_token final String refreshToken = (String) ShareUtils.getValue(this, WEIXIN_REFRESH_TOKEN_KEY, ""); if (TextUtils.isEmpty(refreshToken)) { return; } // 拼裝刷新access_token的url請求地址 String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?" + "appid=" + AppConst.WEIXIN_APP_ID + "&grant_type=refresh_token" + "&refresh_token=" + refreshToken; // 請求執行 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("錯誤信息: " + errorMsg); // 重新請求授權 loginWeixin(WXEntryActivity.this.getApplicationContext(), GeneralAppliction.sApi); } @Override public void onFailure(IOException e) { Logger.e(e.getMessage()); showMessage("登錄失敗"); // 重新請求授權 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("用戶信息獲取結果:" + userInfo.toString()); } @Override public void onError(int errorCode, String errorMsg) { showMessage("錯誤信息: " + 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 請求地址 * @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() {  // 請求失敗,主線程回調  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() {  // 請求出錯,主線程回調  callback.onError(response.code(), response.message());  }  }); } else {  mCallbackHandler.post(new Runnable() {  @Override  public void run() {  try {  // 請求成功,主線程返回請求結果  callback.onSuccess(response.body().string());  } catch (final IOException e) {  // 異常出錯,主線程回調  mCallbackHandler.post(new Runnable() {   @Override   public void run() {   callback.onFailure(e);   }  });  }  }  }); } } } });}// Api通信回調接口public interface ApiCallback<T> { /** * 請求成功 * * @param response 返回結果 */ void onSuccess(T response); /** * 請求出錯 * * @param errorCode 錯誤碼 * @param errorMsg 錯誤信息 */ void onError(int errorCode, String errorMsg); /** * 請求失敗 */ void onFailure(IOException e);}

總結

集成的詳細描述就這樣,至于獲取的用戶信息,小伙伴們應該知道后續自己業務的需求,該怎么處理了。以上就是本文的全部內容了,希望能對大家的學習或者工作帶來一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西充县| 乌兰察布市| 成安县| 锡林浩特市| 洪雅县| 陆川县| 读书| 中超| 西安市| 民县| 连平县| 英吉沙县| 逊克县| 余江县| 扎囊县| 绥江县| 浦北县| 吉安县| 堆龙德庆县| 浠水县| 唐海县| 绍兴市| 诏安县| 扎囊县| 石泉县| 吴堡县| 榆林市| 叶城县| 囊谦县| 深水埗区| 静海县| 彰化县| 淳化县| 额敏县| 龙里县| 舒城县| 中方县| 子长县| 潞西市| 九寨沟县| 五原县|