91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中怎么實現微信登錄

發布時間:2021-06-28 16:14:09 來源:億速云 閱讀:1009 作者:Leah 欄目:移動開發

Android中怎么實現微信登錄,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一、首先在Application的onCreate中寫:

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

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

// MainActivity.java
WXEntryActivity.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. 在開放平臺注冊創建應用,申請登錄權限

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

Android中怎么實現微信登錄

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

Android中怎么實現微信登錄

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

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

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

示例Demo

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

Android中怎么實現微信登錄

如果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對象方便操作):

@Override
public 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/oauth3/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/oauth3/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);
}

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

安庆市| 大姚县| 隆子县| 南召县| 恩平市| 剑川县| 龙井市| 长乐市| 景谷| 茶陵县| 澜沧| 龙江县| 伊宁市| 安丘市| 阜城县| 德州市| 潞西市| 新源县| 莆田市| 南昌县| 义马市| 璧山县| 大新县| 永平县| 酉阳| 台安县| 钟祥市| 米泉市| 丹寨县| 万安县| 开化县| 金溪县| 金门县| 奉新县| 屏东市| 玛多县| 新野县| 恩平市| 漾濞| 会昌县| 陆河县|