微信登錄想必在很多項目中都會用到,最近的項目中就有需求,之前遇到直接就開幹,偶爾會遇到一些小問題,再次記錄一下,以免後期需要中在四處尋找。
第一需要在微信開放平臺上申請相關信息再次就不累述了
第二需要將微信的sdk集成到項目中也很簡單
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
第三就開始擼代碼了,首先需要在
Application中初始化微信sdk,再次我直接寫了一個方法,在Application的create直接調用就可以了方法如下
private void registerToWX() {
//第二個參數是指你應用在微信開放平臺上的AppID
mWxApi = WXAPIFactory.createWXAPI(this, WeiXinConstants.WEIXIN_APP_ID, false);
// 將該app註冊到微信
mWxApi.registerApp(WeiXinConstants.WEIXIN_APP_ID);
}
調用如下
public static IWXAPI mWxApi;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
registerToWX();
}
第四需要在本地創建一個包名爲wxapi的包
包名裏面需要重寫WxEntryActivity這個activity,需要去實現
implements IWXAPIEventHandler這個類
接下來我就直接貼代碼了
public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {
private IWXAPI iwxapi;
private static final String TAG = "WXEntryActivity";
private static final int RETURN_MSG_TYPE_LOGIN = 1; //登錄
private static final int RETURN_MSG_TYPE_SHARE = 2; //分享
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// getSupportActionBar().hide();
// // 隱藏狀態欄
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//接收到分享以及登錄的intent傳遞handleIntent方法,處理結果
iwxapi = WXAPIFactory.createWXAPI(this, WeiXinConstants.WEIXIN_APP_ID, true);
iwxapi.handleIntent(getIntent(), this);
mContext = this;
sharedPreferences = getSharedPreferences("user", MODE_PRIVATE);
ActivityManage.getActivityStackManager().pushPayActivity(WXEntryActivity.this);
}
@Override
public void onReq(BaseReq baseReq) {
}
//請求回調結果處理
@Override
public void onResp(BaseResp baseResp) {
Log.i(TAG, "onResp:------>");
Log.i(TAG, "error_code:---->" + baseResp.errCode);
int type = baseResp.getType(); //類型:分享還是登錄
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_AUTH_DENIED:
//用戶拒絕授權
ShowToast.showToast(mContext, "拒絕授權微信登錄");
case BaseResp.ErrCode.ERR_USER_CANCEL:
//用戶取消
String message = "";
if (type == RETURN_MSG_TYPE_LOGIN) {
message = "取消了微信登錄";
} else if (type == RETURN_MSG_TYPE_SHARE) {
message = "取消了微信分享";
}
ShowToast.showToast(mContext, message);
break;
case BaseResp.ErrCode.ERR_OK:
//用戶同意
if (type == RETURN_MSG_TYPE_LOGIN) {
//用戶換取access_token的code,僅在ErrCode爲0時有效
String code = ((SendAuth.Resp) baseResp).code;
Log.i(TAG, "code:------>" + code);
//這裏拿到了這個code,去做2次網絡請求獲取access_token和用戶個人信息
//getAessToken(WeiXinConstants.WEIXIN_APP_ID, WeiXinConstants.WEIXIN_APP_SECRET, code, "authorization_code");
} else if (type == RETURN_MSG_TYPE_SHARE) {
ShowToast.showToast(mContext, "微信分享成功");
}
break;
}
}
@Override
protected void onPause() {
overridePendingTransition(0, 0);
super.onPause();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e("onNewIntent", "onNewIntent");
setIntent(intent);
if (!iwxapi.handleIntent(intent, this)) {
finish();
}
}
/**
* 獲取微信登錄,用戶授權後的個人信息
*
* @param appid
* @param secret
* @param code
* @param grant_type
*/
private void getAessToken(final String appid, final String secret, final String code, String grant_type) {
// 表單數據
FormBody.Builder builder = new FormBody.Builder();
LoadingUitls.showAuth(mContext);
builder.add("appid", appid);
builder.add("secret", secret);
builder.add("code", code);
builder.add("grant_type", grant_type);
RequestBody formBody = builder.build();
final Request request = new Request.Builder().url()
.post(formBody).build();
okHttpClient.newCall(request).enqueue(callBackAccessToken);
}
// 請求後的回調方法
private Callback callBackAccessToken = new Callback() {
@Override
public void onFailure(Call call, IOException e) {
setResultAccessToken(e.getMessage(), false);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
setResultAccessToken(response.body().string(), true);
}
};
// 顯示請求返回的結果
private void setResultAccessToken(final String msg, final boolean success) {
runOnUiThread(new Runnable() {
@Override
public void run() {
LoadingUitls.close();
JSONObject jsonObject = null;
if (success) {
if (msg != null && msg.length() > 0) {
try {
jsonObject = new JSONObject(msg);
access_token = jsonObject.optString("access_token");
unoip = jsonObject.optString("unionid");
openid = jsonObject.optString("openid");
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(StringCon.TOKEN, access_token);
editor.putString(StringCon.OPENID, openid);
editor.putString(StringCon.UNIONID, unoip);
editor.commit();
getWXUserInfo(access_token, openid, unoip);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
ShowToast.showToast(mContext, "授權失敗");
}
} else {
ShowToast.showToast(mContext, "網絡問題!");
}
}
});
}
/**
* 獲取微信登錄,用戶授權後的個人信息
*
* @param access_token
* @param openid
* @param unionid
*/
private void getWXUserInfo(final String access_token, final String openid, final String unionid) {
// 表單數據
FormBody.Builder builder = new FormBody.Builder();
LoadingUitls.showLogining(mContext);
builder.add("access_token", access_token);
builder.add("openid", openid);
builder.add("unionid", unionid);
RequestBody formBody = builder.build();
final Request request = new Request.Builder().url(NetCont.get_Userinfo)
.post(formBody).build();
okHttpClient.newCall(request).enqueue(callback);
}
// 請求後的回調方法
private Callback callback = new Callback() {
@Override
public void onFailure(Call call, IOException e) {
setResult(e.getMessage(), false);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
setResult(response.body().string(), true);
}
};
// 顯示請求返回的結果
private void setResult(final String msg, final boolean success) {
runOnUiThread(new Runnable() {
@Override
public void run() {
LoadingUitls.close();
JSONObject jsonObject = null;
if (success) {
if (msg != null && msg.length() > 0) {
try {
jsonObject = new JSONObject(msg);
strNickName = jsonObject.getString("nickname");
strSex = jsonObject.getString("sex");
strHeadimgurl = jsonObject.getString("headimgurl");
unoip = jsonObject.getString("unionid");
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(StringCon.USER_NAME, strNickName);
editor.putString(StringCon.SEX, strSex);
editor.putString(StringCon.USER_LOGO, strHeadimgurl);
editor.putString(StringCon.UNIONID, unoip);
editor.putString(StringCon.LOGIN_TYPE, "1"); //
editor.putString(StringCon.BINDWEIXIN, "1"); //
editor.commit();
showViews(true);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
ShowToast.showToast(mContext, "微信登錄失敗");
showViews(false);
}
} else {
ShowToast.showToast(mContext, "網絡問題!");
showViews(false);
}
}
});
}
/**
* 微信登錄
* DevID
* unionid
* Sex
* headimgurl
* NickName
*/
private void showViews(boolean flag) {
if (flag) {
String deviceId = PhoneParameterUtil.getDeviceID();
wxlogin(deviceId, unoip, strSex, strHeadimgurl, strNickName);
} else {
finish();
}
}
}
我這裏網絡請求用的是OKhttp,主要有微信授權登錄,獲取access_token,獲取用戶信息
最後一點也是容易我忘的,記得權限的配置,還有
<!-- 微信登錄 -->
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="xxxxx
</intent-filter>
</activity>
這個必須要寫,不然無法調起微信登錄,以上就是本人在做微信登錄的時候處理的東西
在做的時候有一下兩點需要注意
第一:本地調試的時候需要將微信開放平臺上的簽名替換成dug.keystore的簽名,不然無法調起獲取dbug的簽名可以借用官方提供的apk來獲取
第二:在正式上線的時候記得替換微信開放平臺上的簽名,微信開放平臺上的簽名修改之後可能需要幾分鐘之後纔會生效,所以在替換之後請耐心等幾分鐘之後再去測試,不然調微信就kill了
歡迎大家留言交流