6.鉴于官方demo的复杂性,以及文档中的不完整和不一致性,我提供一个自己简单封装的类,参考一下:
/**
* 用于使用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();
}
}
}
关于其他相关的功能,比如注销什么的,应该相对简单,可以在demo里面找到,我就不说了。
发帖BUG不少啊,一编辑我的链接全都不见了,感觉不会爱了!
我就不贴了,腾讯开发平台,QQ互联开发平台,所有相关东西都在里面,大家自己去找吧。
我也就不上传相关文件了,毕竟下载好贵的,如果实在需要的,可以找我。
再贴下上面代码涉及到的类:
/**
* 存放登录令牌的类
* @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;
}
}
/**
* 该类定义了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();
}
}
二。使用新浪微博账号登录第三方应用
相比来说,新浪微博毕竟省事一些。
我们同样需要注册,创建应用,获得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.貌似没什么可说的,贴上自己的实现供参考:
/**
* 使用新浪微博账号登录时的SSO辅助类
*
* @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());
}
}
}
/**
* 该类定义了微博授权时所需要的参数。
*
* @author SINA
*/
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();
}
}
需要注意的是,以上APP_ID和APP_KEY都需要替换成自己的。
如有疑问或者建议,可以随时留言。
三。关于其他实现方式
其实我们可以使用其他第三方sdk来实现这些功能,比如ShareSDK,他提供了包括QQ,新浪微博,人人网,开心网等等一系列第三方分享和登录等功能,而且有一个明显的好处是,不用分别去学习各自平台的开发方式,而是只需要学习ShareSDK的开发方式之后,就可以实现很多平台的分享,尤其是当我们的应用中需要集成比较多的第三方平台。
但是当我们的应用比较少的集成第三方,或者比较少的集成第三方的功能,使用这种方式无疑会增加包的大小,因为我们同时集成了其他很多用不到的功能。这时候如果能选择本文介绍的方式开发的话,可以减少应用的大小。
大概就这样了,三克油。