標籤:新浪微博 oauth login
原文出自:方傑| http://fangjie.sinaapp.com/?p=75 轉載請註明出處
最終效果示範:http://fangjie.sinaapp.com/?page_id=54
該項目代碼已經放到github:https://github.com/JayFang1993/SinaWeibo
二.擷取使用者資訊並儲存資料庫
上面說到載入AuthActivity有兩種情況,其中一種就是授權成功回調,在授權回調成功後我們就開始通過微博API擷取使用者資訊了,然後儲存資料庫了。這一系列操作我採用主架構模式,將任務發送給MainService來處理。
對於這個任務的具體處理過程,先通過token擷取UID,再通過UID擷取UserInfo。UserInfo中值得注意的是UserIcon是Bitmap類型的,這裡涉及到一個通過url擷取Bitmap的方法,這裡就不細講了。
MainService.java中的doTask方法:
public void doTask(Task task){ Message msg=handler.obtainMessage(); msg.what=task.getTaskID(); switch(task.getTaskID()) { //登入操作 case Task.WEIBO_LOGIN: break; //通過access_token擷取使用者資訊,並儲存到資料庫操作 case Task.GET_USERINFO_BY_TOKEN: { Oauth2AccessToken access_token=(Oauth2AccessToken)task.getParams().get("token"); Log.i("OUTPUT", "access_token:"+access_token.getToken()); /** * 步驟一:用授權碼來擷取使用者Uid */ //請求擷取uid String uid=""; GetUserInfo.reqUID(access_token); //擷取uid do{ uid=GetUserInfo.getUID(); }while(uid.equals("")); /** * 步驟二:通過uid,token擷取UserInfo */ //請求擷取使用者資訊 long _uid=Long.parseLong(uid); UserInfo user=new UserInfo(); GetUserInfo.reqUserInfo(access_token, _uid); //擷取UserInfo do{ user=GetUserInfo.getUserInfo(); }while(user.getUserName().equals("")); user.setUserId(uid); //Log.i("OUTPUT","username:"+user.getUserName()+"userid+"+user.getUserId()+"usericon"+user.getUserIcon()); /** * 步驟三:把UserInfo的資料儲存到資料庫總 */ //建立資料庫 DBUserInfo db=new DBUserInfo(getActivityByName("AuthActivity")); //如果該資料不存在資料庫中 if(db.getUserInfoByUserId(uid)==null) { //插入 db.insertUserInfo(user); Log.i("OUTPUT","儲存資料庫成功"); } //如果該資料已經存在資料庫中 else { //修改 Log.i("OUTPUT","資料修改成功"); } msg.obj="成功";} break; //登入介面擷取使用者資訊顯示操作 case Task.GET_USERINFO_IN_LOGIN: break; default : break; } handler.sendMessage(msg);}上面的微博API操作都是非同步操作所以同樣採取先請求,然後擷取的操作。這種方式在授權部分已經講的很清楚了。
然後就是儲存資料庫的操作,這裡都是最基本的資料庫使用方式了,就是有一點需要注意的是,UserIcon儲存的是BOLB位元據。
GetUserInfo.java //利用微博API擷取使用者資訊的工具方法類
package com.fangjie.weibo.util;import java.io.BufferedInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import org.json.JSONException;import org.json.JSONObject;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.Log;import com.fangjie.weibo.bean.UserInfo;import com.weibo.sdk.android.Oauth2AccessToken;import com.weibo.sdk.android.WeiboException;import com.weibo.sdk.android.api.AccountAPI;import com.weibo.sdk.android.api.UsersAPI;import com.weibo.sdk.android.net.RequestListener;/** * GetUserInfo類 * 通過API擷取使用者資訊 * @author 方傑 * @date 2013-7-29 */public class GetUserInfo { public static String UID=""; private static UserInfo user; /** * 通過accessToken請求使用者資訊UID * @param accessToken */ public static void reqUID(Oauth2AccessToken accessToken) { AccountAPI account=new AccountAPI(accessToken); account.getUid(new RequestListener(){ @Override public void onComplete(String result) { // TODO Auto-generated method stub try { JSONObject object =new JSONObject(result); UID=object.getString("uid"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onError(WeiboException arg0) { // TODO Auto-generated method stub } @Override public void onIOException(IOException arg0) { // TODO Auto-generated method stub } }); } /** * 請求UID之後,擷取UID * @return string */ public static String getUID() { String id=UID; UID=""; return id; } /** * 通過accessToken,uid請求擷取使用者資訊UserInfo(name,icon......) * @param accessToken * @param uid */ public static void reqUserInfo(final Oauth2AccessToken accessToken,long uid) { user=new UserInfo(); UsersAPI userapi=new UsersAPI(accessToken); userapi.show(uid, new RequestListener() { @Override public void onIOException(IOException arg0) { // TODO Auto-generated method stub } @Override public void onError(WeiboException arg0) { // TODO Auto-generated method stub } @Override public void onComplete(String arg0) { // TODO Auto-generated method stub JSONObject object; try { object = new JSONObject(arg0); Bitmap bm=GetUserInfo.getBitmap(object.getString("profile_image_url")); GetUserInfo.user.setUserIcon(bm); GetUserInfo.user.setToken(accessToken.getToken()); GetUserInfo.user.setIsDefault("0"); GetUserInfo.user.setUserName(object.getString("screen_name")); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } });} public static UserInfo getUserInfo() { Log.i("OUTPUT",user.getUserName()); return user; } public static Bitmap getBitmap(String biturl) { Bitmap bitmap=null; try { URL url=new URL(biturl); URLConnection conn=url.openConnection(); InputStream in =conn.getInputStream(); bitmap=BitmapFactory.decodeStream(new BufferedInputStream(in)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return bitmap; }}
DBUserInfo.java //操作使用者資訊的資料庫工具方法類
package com.fangjie.weibo.db;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.util.ArrayList;import java.util.List;import com.fangjie.weibo.bean.UserInfo;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.graphics.drawable.Drawable;import android.util.Log;public class DBUserInfo { private DBHelper dbhelper; public DBUserInfo(Context context) { dbhelper = new DBHelper(context); } /** * 添加使用者資訊 * @param UserInfo */ public void insertUserInfo(UserInfo user) { SQLiteDatabase db = dbhelper.getWritableDatabase(); ByteArrayOutputStream baos=new ByteArrayOutputStream(); user.getUserIcon().compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] usericon=baos.toByteArray(); ContentValues values = new ContentValues(5); values.put(UserInfo.USER_ID,user.getUserId()); values.put(UserInfo.USER_NAME, user.getUserName()); values.put(UserInfo.TOKEN,user.getToken()); values.put(UserInfo.IS_DEFAULT,user.getIsDefault()); values.put(UserInfo.USER_ICON,usericon); db.insert(UserInfo.TB_NAME, null, values);//表名稱 db.close(); } /** * 根據使用者userId擷取使用者物件 * @param String * @return UserInfo */ public UserInfo getUserInfoByUserId(String uid) { SQLiteDatabase db = dbhelper.getReadableDatabase(); Cursor cursor =db.query(UserInfo.TB_NAME, new String[]{UserInfo.ID,UserInfo.IS_DEFAULT,UserInfo.TOKEN, UserInfo.USER_ID,UserInfo.USER_NAME,UserInfo.USER_ICON}, UserInfo.USER_ID +"=?",new String[]{uid}, null, null, null); UserInfo userInfo =null; if(null != cursor) { if(cursor.getCount() >0) { cursor.moveToFirst(); userInfo = new UserInfo(); Long id =cursor.getLong(cursor.getColumnIndex(UserInfo.ID)); String uId = cursor.getString(cursor.getColumnIndex(UserInfo.USER_ID)); String userName = cursor.getString(cursor.getColumnIndex(UserInfo.USER_NAME)); String token = cursor.getString(cursor.getColumnIndex(UserInfo.TOKEN)); String isDefault = cursor.getString(cursor.getColumnIndex(UserInfo.IS_DEFAULT)); byte[] byteIcon = cursor.getBlob(cursor.getColumnIndex(UserInfo.USER_ICON)); userInfo.setId(id); userInfo.setUserId(uId); userInfo.setIsDefault(isDefault); userInfo.setToken(token); userInfo.setToken(token); userInfo.setUserName(userName); if(null !=byteIcon) { Bitmap userIcon=BitmapFactory.decodeByteArray(byteIcon, 0, byteIcon.length); userInfo.setUserIcon(userIcon); } } } db.close(); return userInfo; } /** * 擷取資料庫所有授權使用者資訊 * @param * @return List<UserInfo> */ public List<UserInfo> getAllUserInfo() { List<UserInfo> users=new ArrayList<UserInfo>(); SQLiteDatabase db = dbhelper.getReadableDatabase(); Cursor cursor =db.query(UserInfo.TB_NAME, new String[]{UserInfo.ID,UserInfo.IS_DEFAULT,UserInfo.TOKEN, UserInfo.USER_ID,UserInfo.USER_NAME,UserInfo.USER_ICON}, null,null, null, null, null); UserInfo userInfo =null; while(cursor.moveToNext()) { userInfo = new UserInfo(); Long id =cursor.getLong(cursor.getColumnIndex(UserInfo.ID)); String uId = cursor.getString(cursor.getColumnIndex(UserInfo.USER_ID)); String userName = cursor.getString(cursor.getColumnIndex(UserInfo.USER_NAME)); String token = cursor.getString(cursor.getColumnIndex(UserInfo.TOKEN)); String isDefault = cursor.getString(cursor.getColumnIndex(UserInfo.IS_DEFAULT)); byte[] byteIcon = cursor.getBlob(cursor.getColumnIndex(UserInfo.USER_ICON)); userInfo.setId(id); userInfo.setUserId(uId); userInfo.setIsDefault(isDefault); userInfo.setToken(token); userInfo.setUserName(userName); if(null !=byteIcon) { Bitmap userIcon=BitmapFactory.decodeByteArray(byteIcon, 0, byteIcon.length); Log.i("OUTPUT","dbuserinfo"+userIcon); userInfo.setUserIcon(userIcon); } users.add(userInfo);} db.close(); return users; }}
三.擷取所有授權使用者資訊並顯示在登入介面上
還記得在上面的AuthActivity中我們發送的GET_USERINFO_BY_TOKEN (擷取授權使用者資訊並儲存資料庫)這個任務,這個任務完成後,我們會在refresh()方法中跳到LoginActivity。在LoginActivity的初始時,我們會發送GET_USERINFO_IN_LOGIN(擷取所有授權使用者資訊),在做這個任務處理時也就是資料庫的操作。
//登入介面擷取使用者資訊顯示操作 case Task.GET_USERINFO_IN_LOGIN: { DBUserInfo db=new DBUserInfo(getActivityByName("LoginActivity")); List<UserInfo> users=db.getAllUserInfo(); msg.obj=users; }
其他:
講完上面這些,我突然想講講這個addActivty,reMoveActivty,getActivityByName
/** * UI層向MainService中發送任務的同時,同樣要發送自己Activity, * 以便在MainService中調用refresh(); * @param task */ public static void addActivty(Activity activity) { appActivities.add(activity); } /** * UI層中有向MainService中傳遞Activity,在任務結束後(refresh),應去除該Activity,防止混淆! * eg:在LoginActivity中的GET_USERINFO_IN_LOGIN任務會隨Activity的每次重新載入而開始一次,如果不去除 * activity的話,會導致本次refresh的是上次的activity的執行個體。因為擷取activity是通過getActivityByName,這兩 * 次的activity執行個體的name是相同的。 * @param activity */ public static void reMoveActivty(Activity activity) { appActivities.remove(activity); }
特別是reMoveActivty這個方法,我自己在做項目的時候就忘記了在每次完成任務時去刪除這個Activity執行個體,導致了這樣一個錯誤:
程式啟動的時候會到LoginActivity,這時候做了一次GET_USERINFO_IN_LOGIN,就把LoginAcivity的一個執行個體傳到activities中,當我再次添加一個授權使用者資訊,完成後再次跳到LoginActivity時,這時介面上就沒有任何顯示資訊。因為當第二次跳到LoginActivity時,再次傳一個LoginActivity的執行個體,而我在完成任務後refresh()時,重新整理的是第一次的LoginActivity執行個體,所以對第二次的LoginActivity當然是沒有顯示。
通過上面這三個方法的配合我們就可以由Activity向一些工具類方法傳遞Context內容相關的參數,比如在建立資料庫時需要Context這個參數,還有在工具類中跳轉的時候也需要用到Context參數。雖然這種傳參可能會增加層與層之間的耦合度,但是我目前就這水平,也請大家給我指點。
歡迎各位關注我的個人網站:http://fangjie.sinaapp.com/