編輯:Android開發實例
人人授權認證已聊了兩篇了,這篇重點是整理思路和重構代碼(項目開發過程中開發人員經常干的事)。好了不廢話,下面開始聊今天的內容。
一、人人Auth授權認證流程圖:
二、重構代碼:
1、再次訪問授權頁出現的空白頁,如下圖:
解決方法,修改WebView組件的請求重定向方法,處理代碼如下:
- mWebView.setWebViewClient(new WebViewClient() {
- public boolean shouldOverrideUrlLoading(WebView webView, String url) {
- Log.i(TAG, "shouldOverrideUrlLoading() Redirect URL = " + url);
- if (url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#error=login_denied")) {
- AuthActivity.this.onBackPressed();
- } else if(url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#access_token")) {
- String accessToken = url.substring(url.indexOf("=")+1, url.indexOf("&"));
- Log.i(TAG, "accessToken = " + accessToken);
- // 人人Demo LOG打印: 195789|6.7faefec2274182195287028d00323781.2592000.1367118000-461345584
- // 服務器端返回: 195789%7C6.7faefec2274182195287028d00323781.2592000.1367118000-461345584
- accessToken = accessToken.replace("%7C", "|");
- Log.i(TAG, "Success obtain accessToken = " + accessToken);
- // 存儲AccessToken
- mAuthTokenManager.storeAccessToken(accessToken);
- exchangeSessionKey(accessToken);
- } else {
- webView.loadUrl(url);
- }
- return true;
- }
- public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError errorCode) {
- // 在默認情況下,通過loadUrl(String url)方法,可以順利load。
- // 但是,當load有ssl層的https頁面時,如果這個網站的安全證書在Android無法得到認證,WebView就會變成一個空白頁,
- // 而並不會像PC浏覽器中那樣跳出一個風險提示框。因此,我們必須針對這種情況進行處理。(這個證書限於2.1版本以上的Android 系統才可以)
- // 默認的處理方式,WebView變成空白頁
- // handler.cancel();
- // 接受證書
- handler.proceed();
- }
- @Override
- public void onReceivedError(WebView view, int errorCode,
- String description, String failingUrl) {
- super.onReceivedError(view, errorCode, description, failingUrl);
- AuthActivity.this.onBackPressed();
- }
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- Log.i(TAG, "onPageStarted() URL = " + url);
- // super.onPageStarted(view, url, favicon);
- }
- public void onPageFinished(WebView view, String url) {
- Log.i(TAG, "onPageFinished() URL = " + url);
- // super.onPageFinished(view, url);
- }
- });
2、將有關認證授權信息提取放到認證信息管理類中,代碼如下:
- package com.everyone.android;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import com.everyone.android.entity.Authorization;
- /**
- * 功能描述:認證授權信息管理類
- * @author android_ls
- *
- */
- public final class AuthTokenManager {
- private Context mContext;
- private SharedPreferences mSharedPreferences;
- public AuthTokenManager(Context context){
- this.mContext = context;
- mSharedPreferences = mContext.getSharedPreferences("auth_config", Context.MODE_PRIVATE);
- }
- /**
- * 獲取accessToken
- * @return
- */
- public String getAccessToken() {
- String accessToken = mSharedPreferences.getString("oauth_token", null);
- if (accessToken == null) {
- return null;
- }
- long createTime = mSharedPreferences.getLong("create_oauth_token_time", 0);
- long life = Long.parseLong(accessToken.split("\\.")[2]) * 1000;
- long currenct = System.currentTimeMillis();
- long oneHour = 1000 * 60 * 60;
- if ((createTime + life) < (currenct - oneHour)) {
- Editor editor = mSharedPreferences.edit();
- editor.clear();
- editor.commit();
- return null;
- }
- return accessToken;
- }
- /**
- * 存儲accessToken,
- * @param accessToken
- */
- public void storeAccessToken(String accessToken) {
- Editor editor = mSharedPreferences.edit();
- if (accessToken != null) {
- editor.putString("oauth_token", accessToken);
- editor.putLong("create_oauth_token_time", System.currentTimeMillis());
- } else {
- editor.clear();
- }
- editor.commit();
- }
- /**
- * 在本地存儲Authorization
- * @param auth
- */
- public void save(Authorization auth){
- Editor editor = mSharedPreferences.edit();
- editor.putString("session_key", auth.getSessionKey());
- editor.putString("session_secret", auth.getSessionSecret());
- editor.putLong("expires_in", auth.getExpiresIn());
- editor.putLong("create_session_time", auth.getCreateSessionTime());
- // editor.putString("oauth_token", auth.getOauthToken());
- editor.putLong("userId", auth.getUserId());
- editor.commit();
- }
- /**
- * 從SharedPreference中讀入SessionKey
- */
- private Authorization getAuthBySharedPre() {
- // String oauthToken = mSharedPreferences.getString("oauth_token", null);
- String sessionKey = mSharedPreferences.getString("session_key", null);
- String sessionSecret = mSharedPreferences.getString("session_secret", null);
- long userId = mSharedPreferences.getLong("userId", 0);
- long expires = mSharedPreferences.getLong("expires_in", 0);
- long createTime = mSharedPreferences.getLong("create_session_time", 0);
- long expireTime = createTime + expires;
- Authorization auth = new Authorization();
- // auth.setOauthToken(oauthToken);
- auth.setSessionKey(sessionKey);
- auth.setSessionSecret(sessionSecret);
- auth.setCreateSessionTime(createTime);
- auth.setExpiresIn(expireTime);
- auth.setUserId(userId);
- return auth;
- }
- /**
- * 檢測當前session是否有效
- * @return
- * true - session 有效
- * false - session 無效
- */
- public boolean isSessionValid() {
- Authorization auth = getAuthBySharedPre();
- long current = System.currentTimeMillis();
- if(auth.getSessionKey() != null && auth.getSessionSecret() != null
- && current < auth.getExpiresIn()) {
- return true;
- }
- // sessioin 已過期,刪除SharedPreference中存儲的SessionKey信息
- Editor editor = mSharedPreferences.edit();
- editor.clear();
- editor.commit();
- return false;
- }
- }
3、將服務器端返回的授權認證JSON字符串的解析工作提取
- package com.everyone.android.parse;
- import org.json.JSONException;
- import org.json.JSONObject;
- import com.everyone.android.entity.Authorization;
- /**
- * 功能描述:負責解析Auth認證的JSON字符串
- * @author android_ls
- *
- */
- public final class AuthParse {
- public static Authorization getAuth(String json) throws JSONException {
- JSONObject jsonObject = new JSONObject(json);
- JSONObject jsonRenrenToken = jsonObject.getJSONObject("renren_token");
- String sessionKey = jsonRenrenToken.getString("session_key");
- String sessionSecret = jsonRenrenToken.getString("session_secret");
- long expiresIn = jsonRenrenToken.getLong("expires_in");
- String oauthToken = jsonObject.getString("oauth_token");
- long userId = jsonObject.getJSONObject("user").getLong("id");
- // 對Session過期時間進行處理, Session過期時間 = 系統當前的時間 + 服務器端返回的Session過期時間。
- long createSessionTime = System.currentTimeMillis();
- expiresIn = createSessionTime + expiresIn*1000; // 服務器端返回的Session過期時間單位為秒,因此需要乘以1000
- Authorization auth = new Authorization();
- auth.setOauthToken(oauthToken);
- auth.setSessionKey(sessionKey);
- auth.setSessionSecret(sessionSecret);
- auth.setCreateSessionTime(createSessionTime);
- auth.setExpiresIn(expiresIn);
- auth.setUserId(userId);
- return auth;
- }
- }
4、授權認證界面的處理:
- /**
- * 通過accessToken換取session_key、session_secret和userId
- * @param accessToken
- */
- private void exchangeSessionKey(String accessToken) {
- if (accessToken == null || accessToken.length() < 1) {
- return;
- }
- Map<String, String> parameter = new HashMap<String, String>();
- parameter.put("oauth_token", accessToken);
- AsyncBaseRequest asyncRequest = new AsyncHttpPost(Constant.SESSION_KEY_URL, parameter,
- new ParseCallback (){
- @Override
- public Authorization parse(String json) throws JSONException {
- Log.i(TAG, "result = " + json);
- if(!TextUtils.isEmpty(json)){
- // 服務器端返回的JSON字符串:
- /*{
- "renren_token":
- {
- "session_secret":"52e95c7b02abb0a80a4a80116438063a",
- "expires_in":2595334,
- "session_key":"6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584"
- },
- "oauth_token":"195789|6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584",
- "user":
- {
- "id":461345584
- }
- }*/
- // 解析JSON
- Authorization auth = AuthParse.getAuth(json);
- Log.e(TAG, "auth = " + auth.toString());
- return auth;
- }
- return null;
- }
- },
- new ResultCallback(){
- @Override
- public void onSuccess(final Object result) {
- if (!(result instanceof Authorization)) {
- Log.e(TAG, "網絡請求返回值解析後不是Authorization類型");
- return;
- }
- // 本地存儲Authorization授權認證數據
- mAuthTokenManager.save((Authorization)result);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mWebView != null) {
- mWebView.stopLoading();
- }
- Intent intent = new Intent(AuthActivity.this, EveryoneActivity.class);
- AuthActivity.this.startActivity(intent);
- AuthActivity.this.finish();
- }
- });
- }
- @Override
- public void onFail(int errorCode) {
- Log.e(TAG, "網絡請求返回的errorCode = " + errorCode);
- }
- });
- mDefaultThreadPool.execute(asyncRequest);
- mAsyncRequests.add(asyncRequest);
- }
5、導引界面添加的處理:
- // 檢測accessToken是否有效
- String accessToken = mAuthTokenManager.getAccessToken();
- LogUtil.i(TAG, "accessToken = " + accessToken);
- Intent intent = new Intent();
- if (accessToken == null) {
- intent.setClass(this, AuthActivity.class);
- startActivity(intent);
- return;
- }
- // 檢測Session是否有效
- if (mAuthTokenManager.isSessionValid()) {
- intent.setClass(this, EveryoneActivity.class);
- startActivity(intent);
- finish();
- } else {
- // accessToken有效,Session失效
- exchangeSessionKey(accessToken);
- }
注:當accessToken有效,Session失效時的處理,與授權界面的通過accessToken換取session_key、session_secret和userId基本一致,就不貼代碼了。
6、Auth信息實體類代碼:
- package com.everyone.android.entity;
- /**
- * 功能描述:Auth信息實體類
- * @author android_ls
- *
- */
- public class Authorization {
- private String oauthToken; // accessToken
- private long userId; // 當前登錄用戶的uid
- private String sessionKey; // Session key
- private String sessionSecret; // Session Secret
- private long expiresIn; // Session 過期時間
- private long createSessionTime; // 創建時間(從服務器端獲取到時的本地時間)
- public String getOauthToken() {
- return oauthToken;
- }
- public void setOauthToken(String oauthToken) {
- this.oauthToken = oauthToken;
- }
- public long getUserId() {
- return userId;
- }
- public void setUserId(long userId) {
- this.userId = userId;
- }
- public String getSessionKey() {
- return sessionKey;
- }
- public void setSessionKey(String sessionKey) {
- this.sessionKey = sessionKey;
- }
- public String getSessionSecret() {
- return sessionSecret;
- }
- public void setSessionSecret(String sessionSecret) {
- this.sessionSecret = sessionSecret;
- }
- public long getExpiresIn() {
- return expiresIn;
- }
- public void setExpiresIn(long expiresIn) {
- this.expiresIn = expiresIn;
- }
- public long getCreateSessionTime() {
- return createSessionTime;
- }
- public void setCreateSessionTime(long createSessionTime) {
- this.createSessionTime = createSessionTime;
- }
- public String toString() {
- StringBuilder authResult = new StringBuilder();
- authResult.append(" oauth_token = ").append(oauthToken);
- authResult.append("\n session_key = ").append(sessionKey);
- authResult.append("\n session_secret = ").append(sessionSecret);
- authResult.append("\n expires_in = ").append(expiresIn);
- authResult.append("\n userId = ").append(userId);
- return authResult.toString();
- }
- }
有關人人Auth認證的到這裡就聊完了。
轉自:http://blog.csdn.net/android_ls/article/details/8748901
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
Android中的翻轉動畫效果的實現,首先看一下運行效果如上圖所示. Android中並沒有提供直接做3D翻轉的動畫,所以關於3D翻轉的動畫效果需要我們自己實現,
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
Activity與Service之間交互並播放歌曲,為了方便,我把要播放的歌曲定死了,大家可以靈活改進 MService:代碼如下:package c