轉載--http://www.eoeandroid.com/thread-325071-1-1.htmlhtml
最近公司因爲項目要求,在應用中集成了QQ和新浪微博登陸的功能,之前並無接觸過這方面的東西,前2天研究清楚,並實現了,寫點心得和你們分享,同時也做爲學習記錄保留下來。 廢話不說,直入正題了。
一。使用QQ帳號登陸第三方應用
這裏的第三方應用指的固然是咱們本身開發的應用。
騰訊開發平臺是一個比較大的開放平臺,它包括了騰訊微博開發平臺,微信平臺等諸多平臺,而咱們所須要用到的東西,都在QQ互聯開放平臺。之因此在一開始就說明這一點是由於,擼主以前由於沒搞清楚他們之間的關係,走了很多彎路,因此但願你們可以注意到。
1. 在開發以前,首先要使用QQ號登陸平臺,而後完善開發者信息成爲開發者,以後,要在管理中心,建立你的應用,其中包括完善不少關於你的應用的信息。(關於這部分的詳細信息,請查看官方在線文檔開發者註冊和android應用註冊)。
2.當咱們成功建立 了應用以後,會得到APP ID,這個ID在開發中是必須的。
3.QQ互聯SDK,前往該網頁,能夠下載官方的sdk資料,其中 包括了jar文件,demo,以及詳細的開發說明文檔。
4.(警醒)開發的第一步,首先要把所須要的jar文件導入到咱們的工程中去,在上一步下載的SDK文檔中,咱們會發現有一個open_sdk.jar文件,按照說明文檔導入進去,可是咱們會發如今說明文檔中分明提到了2個jar文件,騰訊開發平臺SDK在這個連接中下載到相應的文件以後,咱們會發現它和以前下載的QQ互聯文件幾乎同樣,區別在於開發說明文檔在細節上的區別,以及JAR文件的不一樣。咱們剛纔提到的所缺乏的一個jar文件,在這就能夠找到了。可是須要特別注意的是,有些人一看,好像2個jar文件都在這裏,那就直接把這2個導入進去開發吧!恭喜你成功掉入陷阱了!咱們仔細對比會發現,在騰訊SDK和QQ互聯sdk中的open_sdk.jar,他們的大小是不同的,這2個文件是有區別的。擼主也是在這裏糾結了好久,代碼完成後沒有提示錯誤,可是運行總是崩掉,後來發現這個問題以後,一陣無語。
簡言之,將QQ互聯sdk中的open_sdk.jar以及騰訊sdk中的mta_sdk_XXX.jar導入到工程以後,能夠按照開發文檔,繼續往下進行。
5.關於AndroidManifest的配置,開發文檔比較詳盡,不贅述。
6.鑑於官方demo的複雜性,以及文檔中的不完整和不一致性,我提供一個本身簡單封裝的類,參考一下:
[mw_shl_code=java,true]/**
* 用於使用QQ互聯受權,登陸的輔助類
*
* @author totoro
* @since 2014-02-28
*/
public class TencentQQHelper {
public static final String APP_ID = "101025815";
public static final String SCOPE = "get_simple_userinfo";
public Tencent tencent;
public Context context;
public UserInfo userInfo;
public TencentQQHelper(Context context) {
this.context = context;
tencent = Tencent.createInstance(APP_ID, context.getApplicationContext());
}
/**
* 登陸
* @since 2014-02-28
*/
public void login() {
if (!tencent.isSessionValid()) {
tencent.login((Activity) context, SCOPE, new BaseUIListener() {
@Override
protected void doComplete(JSONObject obj) {
TencentQQToken token = new TencentQQToken();
try {
token.setOpenid(obj.getString("openid"));
token.setAccess_token(obj.getString("access_token"));
token.setExpires_in(obj.getString("expires_in"));
} catch (JSONException e) {
e.printStackTrace();
}
QQTokenKeeper.writeAccessToken(context, token);
userInfo = new UserInfo(context, tencent.getQQToken());
getUserInfo();
}
});
} else {
tencent.logout(context);
}
}
/**
* 獲取用戶信息
* @since 2014-02-28
*/
public void getUserInfo() {
userInfo.getUserInfo(new BaseUIListener() {
@Override
protected void doComplete(JSONObject obj) {
Intent intent = new Intent(context,UserInfoActivity.class);
Bundle extras = new Bundle();
try {
extras.putString("name", obj.getString("nickname"));
} catch (JSONException e) {
e.printStackTrace();
}
intent.putExtras(extras);
context.startActivity(intent);
}
});
}
/**
* 用戶受權和獲取用戶信息的回調
*
* @author totoro
*/
public class BaseUIListener implements IUiListener {
@Override
public void onComplete(Object response) {
doComplete((JSONObject) response);
}
protected void doComplete(JSONObject obj) {
}
@Override
public void onError(UiError e) {
Toast.makeText(context,e.errorMessage, Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel() {
Toast.makeText(context,"取消操做", Toast.LENGTH_SHORT).show();
}
}
}[/mw_shl_code]
關於其餘相關的功能,好比註銷什麼的,應該相對簡單,能夠在demo裏面找到,我就不說了。
發帖BUG很多啊,一編輯個人連接全都不見了,感受不會愛了!
我就不貼了,騰訊開發平臺,QQ互聯開發平臺,全部相關東西都在裏面,你們本身去找吧。
我也就不上傳相關文件了,畢竟下載好貴的,若是實在須要的,能夠找我。
再貼下上面代碼涉及到的類:
[mw_shl_code=java,true]/**
* 存放登陸令牌的類
* @author totoro
*
*/
public class TencentQQToken {
private String openid;
private String access_token;
private String expires_in;
public TencentQQToken() {}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
}
[/mw_shl_code]
[mw_shl_code=java,true]/**
* 該類定義了QQ互聯受權時所須要的參數
*
* @author totoro
* @since 2014-02-28
*/
public class QQTokenKeeper {
private static final String PREFERENCES_NAME = "tencent_qq_token";
private static final String KEY_OPENID = "openid";
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_EXPIRES_IN = "expires_in";
/**
* 保存 Token 對象到 SharedPreferences。
*
* @param context 應用程序上下文環境
* @param token Token 對象
*/
public static void writeAccessToken(Context context, TencentQQToken token) {
if (null == context || null == token) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.putString(KEY_OPENID, token.getOpenid());
editor.putString(KEY_ACCESS_TOKEN, token.getAccess_token());
String expires_in = token.getExpires_in();
editor.putLong(KEY_EXPIRES_IN, System.currentTimeMillis() + Long.parseLong(expires_in) * 1000);
editor.commit();
}
/**
* 從 SharedPreferences 讀取 TencentQQToken 信息。
*
* @param context 應用程序上下文環境
*
* @return 返回 TencentQQToken 對象
*/
public static TencentQQToken readAccessToken(Context context) {
if (null == context) {
return null;
}
TencentQQToken token = new TencentQQToken();
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
token.setOpenid(pref.getString(KEY_OPENID, ""));
token.setAccess_token(pref.getString(KEY_ACCESS_TOKEN, ""));
long expires_in = (pref.getLong(KEY_EXPIRES_IN, -1) - System.currentTimeMillis())/1000;
token.setExpires_in(Long.toString(expires_in));
return token;
}
/**
* 清空 SharedPreferences 中 Token信息。
*
* @param context 應用程序上下文環境
*/
public static void clear(Context context) {
if (null == context) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.clear();
editor.commit();
}
}
[/mw_shl_code]
二。使用新浪微博帳號登陸第三方應用
相比來講,新浪微博畢竟省事一些。
咱們一樣須要註冊,建立應用,得到APP_KEY(和QQ的APP_ID相似)。經過開發咱們能夠發現,他和QQ互聯的開發模式很是類似。
1. http://open.weibo.com/wiki/SDK#Android_SDK 咱們在這裏下載到所須要的文件後,能夠找到一份比較詳細的開發文檔。同時有demo可供參考,不過有不一樣的是,這裏咱們不經過導入jar文件的方式來引用,而是要將一個做爲library的工程WeiboSDk,導入到eclipse,而後add到本身的工程,具體見文檔。
2.在登陸入口方面,QQ互聯是提供了全部接口,咱們本身完成從按鈕到接口的實現;而新浪微博則是爲咱們提供了封裝好的登陸按鈕,咱們須要在佈局文件中添加新浪的登陸按鈕來實現登陸,登陸按鈕分爲數種,具體使用可見文檔。顯然這個比QQ省事的多。
3.貌似沒什麼可說的,貼上本身的實現供參考:
[mw_shl_code=java,true]/**
* 使用新浪微博帳號登陸時的SSO輔助類
*
* 2014-02-27
* @author totoro
*
*/
public class SinaWeiboSSOHelper {
/**
* 用於使用新浪微博帳號登陸的APP KEY
*/
public static final String APP_KEY = "809484557";
/**
* 使用新浪微博帳號登陸時的受權默認回調頁
*/
public static final String REDIRECT_URL = "https://api.weibo.com/oauth2/default.html";
/**
* 用於新浪微博登陸的受權參數
*/
public static final String SCOPE = "email";
public AuthInfo authInfo;
public Context context;
public AuthListener authListener;
public SinaWeiboSSOHelper(Context context) {
this.context = context;
// 建立受權認證信息
authInfo = new AuthInfo(context, APP_KEY, REDIRECT_URL, SCOPE);
authListener = new AuthListener();
}
/**
* 登入按鈕的監聽器,接收受權結果。
*/
@SuppressLint("SimpleDateFormat")
private class AuthListener implements WeiboAuthListener {
@Override
public void onComplete(Bundle values) {
Oauth2AccessToken accessToken = Oauth2AccessToken.parseAccessToken(values);
if (accessToken != null && accessToken.isSessionValid()) {
SinaAccessTokenKeeper.writeAccessToken(context, accessToken);
UsersAPI usersAPI = new UsersAPI(accessToken);
usersAPI.show(Long.parseLong(accessToken.getUid()), new UserRequstListener());
}
}
@Override
public void onWeiboException(WeiboException e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel() {
Toast.makeText(context,"取消受權", Toast.LENGTH_SHORT).show();
}
}
/**
* 使用UsersAPI獲取用戶信息時須要的請求接口
*
* 2014-02-26
* @author totoro
*
*/
private class UserRequstListener implements RequestListener {
@Override
public void onComplete(String response) {
if (!TextUtils.isEmpty(response)) {
try {
JSONObject obj = new JSONObject(response);
/**
* 將獲取到的用戶信息發送到即將跳轉到的我的界面
*/
Intent intent = new Intent(context,UserInfoActivity.class);
Bundle extras = new Bundle();
extras.putString("name", obj.getString("screen_name"));
extras.putString("location", obj.getString("location"));
intent.putExtras(extras);
context.startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Override
public void onComplete4binary(ByteArrayOutputStream responseOS) {
// TODO Auto-generated method stub
}
@Override
public void onIOException(IOException e) {
Log.v("IOException",e.getMessage());
}
@Override
public void onError(WeiboException e) {
Log.v("Error",e.getMessage());
}
}
}
[/mw_shl_code]
[mw_shl_code=java,true]/**
* 該類定義了微博受權時所須要的參數。
*
* @author SINA
* @since 2013-10-07
*/
public class SinaAccessTokenKeeper {
private static final String PREFERENCES_NAME = "sina_weibo_token";
private static final String KEY_UID = "uid";
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_EXPIRES_IN = "expires_in";
/**
* 保存 Token 對象到 SharedPreferences。
*
* @param context 應用程序上下文環境
* @param token Token 對象
*/
public static void writeAccessToken(Context context, Oauth2AccessToken token) {
if (null == context || null == token) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.putString(KEY_UID, token.getUid());
editor.putString(KEY_ACCESS_TOKEN, token.getToken());
editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
editor.commit();
}
/**
* 從 SharedPreferences 讀取 Token 信息。
*
* @param context 應用程序上下文環境
*
* @return 返回 Token 對象
*/
public static Oauth2AccessToken readAccessToken(Context context) {
if (null == context) {
return null;
}
Oauth2AccessToken token = new Oauth2AccessToken();
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
token.setUid(pref.getString(KEY_UID, ""));
token.setToken(pref.getString(KEY_ACCESS_TOKEN, ""));
token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0));
return token;
}
/**
* 清空 SharedPreferences 中 Token信息。
*
* @param context 應用程序上下文環境
*/
public static void clear(Context context) {
if (null == context) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.clear();
editor.commit();
}
}
[/mw_shl_code]
須要注意的是,以上APP_ID和APP_KEY都須要替換成本身的。
若有疑問或者建議,能夠隨時留言。
三。關於其餘實現方式
其實咱們可使用其餘第三方sdk來實現這些功能,好比ShareSDK,他提供了包括QQ,新浪微博,人人網,開心網等等一系列第三方分享和登陸等功能,並且有一個明顯的好處是,不用分別去學習各自平臺的開發方式,而是隻須要學習ShareSDK的開發方式以後,就能夠實現不少平臺的分享,尤爲是當咱們的應用中須要集成比較多的第三方平臺。
可是當咱們的應用比較少的集成第三方,或者比較少的集成第三方的功能,使用這種方式無疑會增長包的大小,由於咱們同時集成了其餘不少用不到的功能。這時候若是能選擇本文介紹的方式開發的話,能夠減小應用的大小。
大概就這樣了,三克油。java