Android新浪微部落格戶端(四)——添加多個賬戶及認證

來源:互聯網
上載者:User

標籤:新浪微博   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/ 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.