




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android中怎么實現(xiàn)微信登錄
Android中怎么實現(xiàn)微信登錄,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面在下將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。一、首先在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、在開放平臺注冊創(chuàng)建應(yīng)用,申請登錄權(quán)限2、下載sdk,拷貝相關(guān)文件到項目工程目錄3、全局初始化微信組件4、請求授權(quán)登錄,獲取code5、通過code獲取授權(quán)口令access_token6、在第5步判斷access_token是否存在和過期7、如果access_token過期無效,就用refresh_token來刷新8、使用access_token獲取用戶信息1.在開放平臺注冊創(chuàng)建應(yīng)用,申請登錄權(quán)限這一步其實不用怎么講,無法就是在微信開放平臺上注冊一個賬號,然后創(chuàng)建移動應(yīng)用。需要注意的是:應(yīng)用簽名的部分此處應(yīng)用簽名我使用的是線上的key的md5,關(guān)于這個需要注意的問題可以看:Android的簽名總結(jié)2.下載sdk,拷貝相關(guān)文件到項目工程目錄開發(fā)工具包(SDK)的下載:可以使用微信分享、登錄、收藏、支付等功能需要的庫以及文件示例Demo下載后把libammsdk.jar文件拷貝到AS工程的libs目錄,并把示例Demo里源文件目錄下的wxapi目錄整個拷貝到,工程目錄的src下的根包下:如果wxapi這個文件夾放的位置不對,講無法登錄,微信sdk無法找到登錄的Activity授權(quán)功能。然后在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.請求授權(quán)登錄,獲取code為了同一業(yè)務(wù)的單一原則我把微信相關(guān)的都統(tǒng)一封裝到了wxapi包下和WXEntryActivity中://
實現(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)接口注冊
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
微信服務(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)用的作用域,獲取個人信息
req.scope
=
"snsapi_userinfo";
/**
*
用于保持請求和回調(diào)的狀態(tài),授權(quán)請求后原樣帶回給第三方
*
為了防止csrf攻擊(跨站請求偽造攻擊),后期改為隨機數(shù)加session來校驗
*/
req.state
=
"app_wechat";
api.sendReq(req);
}
//
微信發(fā)送請求到第三方應(yīng)用時,會回調(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ā)送到微信的請求處理后的響應(yīng)結(jié)果,會回調(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;
}
}
}小伙伴有疑問code是啥玩意:第三方通過code進行獲取access_token的時候需要用到,code的超時時間為10分鐘,一個code只能成功換取一次access_token即失效。code的臨時性和一次保障了微信授權(quán)登錄的安全性。第三方可通過使用https和state參數(shù),進一步加強自身授權(quán)登錄的安全性。這樣客戶端使用的地方只要:WXEntryActivity.loginWeixin(MainActivity.this,
GeneralAppliction.sApi);5.通過code獲取授權(quán)口令access_token我們在onResp的回調(diào)方法中獲取了code,然后通過code獲取授權(quán)口令access_token:/**
*
獲取授權(quán)口令
*/
private
void
getAccessToken(String
code)
{
String
url
=
"/sns/oauth3/access_token?"
+
"appid="
+
AppConst.WEIXIN_APP_ID
+
"&secret="
+
AppConst.WEIXIN_APP_SECRET
+
"&code="
+
code
+
"&grant_type=authorization_code";
//
網(wǎng)絡(luò)請求獲取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("登錄失敗");
}
});
}
/**
*
處理獲取的授權(quán)信息結(jié)果
*
@param
response
授權(quán)信息結(jié)果
*/
private
void
processGetAccessTokenResult(String
response)
{
//
驗證獲取授權(quán)口令返回的信息是否成功
if
(validateSuccess(response))
{
//
使用Gson解析返回的授權(quán)口令信息
WXAccessTokenInfo
tokenInfo
=
mGson.fromJson(response,
WXAccessTokenInfo.class);
Logger.e(tokenInfo.toString());
//
保存信息到手機本地
saveAccessInfotoLocation(tokenInfo);
//
獲取用戶信息
getUserInfo(tokenInfo.getAccess_token(),
tokenInfo.getOpenid());
}
else
{
//
授權(quán)口令獲取失敗,解析返回錯誤信息
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是否存在和過期在回調(diào)的onResp方法中獲取code后,處理access_token是否登錄過或者過期的問題://
從手機本地獲取存儲的授權(quán)口令信息,判斷是否存在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);
}判斷授權(quán)口令是否有效:/**
*
判斷accesstoken是過期
*
@param
accessToken
token
*
@param
openid
授權(quán)用戶唯一標識
*/
private
void
isExpireAccessToken(final
String
accessToken,
final
String
openid)
{
String
url
=
"/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
=
"/sns/oauth3/refresh_token?"
+
"appid="
+
AppConst.WEIXIN_APP_ID
+
"&grant_type=refresh_token"
+
"&refresh_token="
+
refreshToken;
//
請求執(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("錯誤信息:
"
+
errorMsg);
//
重新請求授權(quán)
loginWeixin(WXEntryActivity.this.getApplicationContext(),
GeneralAppliction.sApi);
}
@Override
public
void
onFailure(IOException
e)
{
Logger.e(e.getMessage());
showMessage("登錄失敗");
//
重新請求授權(quán)
loginWeixin(WXEntryActivity.this.getApplicationContext(),
GeneralAppliction.sApi);
}
});
}8.使用access_token獲取用戶信息/**
*
獲取用戶信息
*
/
private
void
getUserInfo(String
access_token,
String
openid)
{
String
url
=
"/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("錯誤信息:
"
+
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
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工業(yè)機器人運維員理論改練習(xí)試卷附答案
- 2025年膽量心理測試題及答案
- 2025年電力電子的考試題及答案
- 2025年興化大學(xué)面試試題及答案
- 2025年圖館會面試題及答案
- 2025年人格權(quán)法的試題及答案
- 2025年商業(yè)銀行信貸試題及答案
- 2025年壞人腦力測試題及答案
- 2025年流浪記的測試題及答案
- 2025年青島自招面試試題及答案
- 《橋梁工程計算書》word版
- 中華人民共和國特種設(shè)備安全法(節(jié)選)
- 籃球比賽計分表
- 施工現(xiàn)場安全隱患檢查(附標準規(guī)范)
- 吞咽障礙及吞咽功能的評定
- 拱涵計算書-6.0m-1m
- 數(shù)字電子技術(shù)課程設(shè)計報告(數(shù)字積分器)
- 高中有機化學(xué)必修模塊與選修模塊的銜接
- BBC美麗中國英文字幕
- 《自然保護區(qū)綜合科學(xué)考察規(guī)程》
- JJF(皖)105-2020 小型蒸汽滅菌器溫度、壓力參數(shù)校準規(guī)范
評論
0/150
提交評論