上一博文中讲解了auth2.0认证的步骤,已经效果图的展示,不过说实话,效果图则会真心的好丑的,等不了大雅之堂,姑且请各位看官勿喷。谢谢~谢谢~^_^
在这一篇我会详细讲解auth2.0的授权认证过程,不过详细说明之前需要特别提到weibosdkcore.jar这个关键的jar包。
这个包里面有新浪微博客户端的核心代码,是一个核心的jar包。需要添加中开发者新建的app工程文件中,我是用的是adt(android developer tools)安卓开放工具——也就是eclipse加上了android开发插件——哈哈哈……
那如何把这个核心的jar包添加到工程文件中呢?在新建的工程文件中,有一个libs的文件夹,把weibosdkcore.jar这个包复制到该文件夹下即可。
可能有些人复制到libs文件夹下还是不行,这个时候再次查看工程文件中的android private libraries和android dependencies中这两个文件,鼠标点击右键,从菜单中找到build path->configu build path 从打开的选项卡中找到libraries,点击add external jars,再次把weibosdkcore.jar这个jar包添加到工程文件中,这时候即可解决问题。
好了,把新浪微博的核心的jar包添加到工程文件中即可进行开发了,下面详细讲解auth2.0的认证过程-代码说明。
这个类对应于上一篇中auth2.0的授权认证过程。
public class WBAuthCodeActivity extends Activity
{
private static final String TAG = "WBAuthCodeActivity";
/**
* WeiboSDKDemo 程序的 APP_SECRET。 请注意:请务必妥善保管好自己的
* APP_SECRET,不要直接暴露在程序中,此处仅作为一个DEMO来演示。
*/
private static final String WEIBO_DEMO_APP_SECRET = "你自己的app_secret值";
/** 通过 code 获取 Token 的 URL */
private static final String OAUTH2_ACCESS_TOKEN_URL = "https://open.weibo.cn/oauth2/access_token";
/** 获取 Token 成功或失败的消息 */
private static final int MSG_FETCH_TOKEN_SUCCESS = 1;
private static final int MSG_FETCH_TOKEN_FAILED = 2;
/** UI 元素列表 */
private TextView mNote;
private TextView mCodeText;
private TextView mTokenText;
private Button mCodeButton;
private Button mAuthCodeButton;
/** 微博 Web 授权接口类,提供登陆等功能 */
private WeiboAuth mWeiboAuth;
/** 获取到的 Code */
private String mCode;
/** 获取到的 Token */
private Oauth2AccessToken mAccessToken;
/**
* @see {@link Activity#onCreate}
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth_code);
// 初始化控件
mNote = (TextView) findViewById(R.id.note);
mNote.setMovementMethod(LinkMovementMethod.getInstance());
mCodeText = (TextView) findViewById(R.id.code_text);
mTokenText = (TextView) findViewById(R.id.token_text);
mCodeButton = (Button) findViewById(R.id.code);
mAuthCodeButton = (Button) findViewById(R.id.auth_code);
mAuthCodeButton.setEnabled(false);
/**
* 初始化微博对象 该微博类包含在weibo-core.jar包中,可以直接使用,注意他的参数值。
* 第一个参数是app_key值,这个值是开发者在新浪开放平台创建应用之后给定的值,如果不清楚,请参考之前的博文。
* 第二个值是回调地址,该地址我在之前的博文中也详细的说明过,请参考
* 第三个值是授权地址,该值新浪也有提供
* SCOPE =
* "email,direct_messages_read,direct_messages_write,"
* + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
* + "follow_app_official_microblog," + "invitation_write";
* Scope 是 OAuth2.0 授权机制中 authorize 接口的一个参数。通过 Scope,平台将开放更多的微博
* 核心功能给开发者,同时也加强用户隐私保护,提升了用户体验,用户在新 OAuth2.0 授权页中有权利
* 选择赋予应用的功能。
* 这里可以直接复制使用即可
**/
mWeiboAuth = new WeiboAuth(this, Constants.APP_KEY, Constants.REDIRECT_URL, Constants.SCOPE);
// 第一步:获取 Code,这个按钮相当于点击获取code的按钮,请参考我在上一篇博文中发布的图片。
mCodeButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
//这里相当于auth2.0授权认证步骤中的A步。
//注意这里的参数,第一个参数是一个回调监听器,第二个值是一个证书类型,该值为0指明获取的是code值
//请求成功之后,服务器会返回客户端code值,code值的获取就是通过new AuthListener()这个监听器获取到的,服务器响应之后
//会自动调用该监听器
mWeiboAuth.authorize(new AuthListener(), WeiboAuth.OBTAIN_AUTH_CODE);
}
});
// 第二步:通过 Code 获取 Token,这个按钮相当于点击获取Token的按钮,请参考我在上一篇博文中发布的图片。
mAuthCodeButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
//该方法相当于auth2.0认证的C步
//参数mCode就是上面获取到的code值
//参数WEIBO_DEMO_APP_SECRET 就是开发者申请到的app_secret值
fetchTokenAsync(mCode, WEIBO_DEMO_APP_SECRET);
}
});
}
/**
* 微博认证授权回调类。
* 微博服务器响应之后,自动调用该类的onComplete方法,返回code值。
*/
class AuthListener implements WeiboAuthListener
{
@Override
public void onComplete(Bundle values)
{
if (null == values)
{
Toast.makeText(WBAuthCodeActivity.this,
R.string.weibosdk_demo_toast_obtain_code_failed, Toast.LENGTH_SHORT).show();
return;
}
String code = values.getString("code");
if (TextUtils.isEmpty(code))
{
Toast.makeText(WBAuthCodeActivity.this,
R.string.weibosdk_demo_toast_obtain_code_failed, Toast.LENGTH_SHORT).show();
return;
}
mCode = code;
mCodeText.setText(code);
mAuthCodeButton.setEnabled(true);
mTokenText.setText("");
Toast.makeText(WBAuthCodeActivity.this, R.string.weibosdk_demo_toast_obtain_code_success, Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel()
{
Toast.makeText(WBAuthCodeActivity.this, R.string.weibosdk_demo_toast_auth_canceled, Toast.LENGTH_LONG).show();
}
@Override
public void onWeiboException(WeiboException e)
{
UIUtils.showToast(WBAuthCodeActivity.this, "Auth exception : " + e.getMessage(), Toast.LENGTH_LONG);
}
}
/**
* 该 Handler 配合 {@link RequestListener} 对应的回调来更新 UI。
*/
private Handler mHandler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
case MSG_FETCH_TOKEN_SUCCESS:
// 显示 Token 获取成功,得到通知,
String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new java.util
.Date(mAccessToken.getExpiresTime()));
String format = getString(R.string.weibosdk_demo_token_to_string_format_1);
mTokenText.setText(String.format(format, mAccessToken.getToken(), date));
mAuthCodeButton.setEnabled(false);
Toast.makeText(WBAuthCodeActivity.this, R.string.weibosdk_demo_toast_obtain_token_success,
Toast.LENGTH_SHORT).show();
//启动首页,进入主界面
Intent intent = new Intent(WBAuthCodeActivity.this, HomeAcitivity.class);
startActivity(intent);
break;
case MSG_FETCH_TOKEN_FAILED:
Toast.makeText(WBAuthCodeActivity.this, R.string.weibosdk_demo_toast_obtain_token_failed, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
};
};
/**
* 异步获取 Token。
*
* @param authCode
* 授权 Code,该 Code 是一次性的,只能被获取一次 Token
* @param appSecret
* 应用程序的 APP_SECRET,请务必妥善保管好自己的 APP_SECRET,
* 不要直接暴露在程序中,此处仅作为一个DEMO来演示。
*/
public void fetchTokenAsync(String authCode, String appSecret)
{
WeiboParameters requestParams = new WeiboParameters();
requestParams.add(WBConstants.AUTH_PARAMS_CLIENT_ID, Constants.APP_KEY);
requestParams.add(WBConstants.AUTH_PARAMS_CLIENT_SECRET, appSecret);
requestParams.add(WBConstants.AUTH_PARAMS_GRANT_TYPE, "authorization_code");
requestParams.add(WBConstants.AUTH_PARAMS_CODE, authCode);
requestParams.add(WBConstants.AUTH_PARAMS_REDIRECT_URL, Constants.REDIRECT_URL);
/**
* 请注意: {@link RequestListener} 对应的回调是运行在后台线程中的, 因此,需要使用 Handler 来配合更新
* UI。
* 参数说明:
* OAUTH2_ACCESS_TOKEN_URL 该地址是请求地址,服务器配置的
* requestParams 封装的参数,使用jsonObject封装,这里com.sina.weibo.sdk.auth.WeiboParameters 是weibosdk-core.jar包已经
* 处理好的工具类,可以直接使用,用于封装参数,使用key-value对的形式
* 第三个参数post 指明请求类型post类型
* 第四个参数比较重要,需要重点理解,因为新浪微博服务器在响应结束之后,都会回调该监听器的oncomplete方法,把响应的数据
* 封装进response参数中,当然,如果出错,则回调onIOException onError方法 onComplete4binary是一个数据流,目前开发没有使用
* 可以先不考虑它
*/
AsyncWeiboRunner.request(OAUTH2_ACCESS_TOKEN_URL, requestParams, "POST", new RequestListener()
{
@Override
public void onComplete(String response)
{
LogUtil.d(TAG, "Response: " + response);
// 获取 Token 成功,获取到的code值和Token值,需要在本次登陆之后保存,不能丢弃,因为后期的获取微博的大部分接口都需要该值。
Oauth2AccessToken token = Oauth2AccessToken.parseAccessToken(response);
if (token != null && token.isSessionValid())
{
LogUtil.d(TAG, "Success! " + token.toString());
mAccessToken = token;
<span style="white-space:pre"> </span>//此处保存使用了<span style="font-family: Arial, Helvetica, sans-serif;">AccessTokenKeeper工具类,该类没有在weibosdk-core.jar包中,该类是demo里面定义的,可以参考demo中</span>
AccessTokenKeeper.writeAccessToken(WBAuthCodeActivity.this,mAccessToken);
<span style="white-space:pre"> </span>//获取成功之后,通知主线程
mHandler.obtainMessage(MSG_FETCH_TOKEN_SUCCESS).sendToTarget();
} else
{
LogUtil.d(TAG, "Failed to receive access token");
}
}
@Override
public void onComplete4binary(ByteArrayOutputStream responseOS)
{
LogUtil.e(TAG, "onComplete4binary...");
mHandler.obtainMessage(MSG_FETCH_TOKEN_FAILED).sendToTarget();
}
@Override
public void onIOException(IOException e)
{
LogUtil.e(TAG, "onIOException: " + e.getMessage());
mHandler.obtainMessage(MSG_FETCH_TOKEN_FAILED).sendToTarget();
}
@Override
public void onError(WeiboException e)
{
LogUtil.e(TAG, "WeiboException: " + e.getMessage());
mHandler.obtainMessage(MSG_FETCH_TOKEN_FAILED).sendToTarget();
}
});
}
}
该界面的布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".WBAuthCodeActivity" >
<TextView
android:id="@+id/note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/weibosdk_demo_obtain_token_via_code_hint" />
<Button
android:id="@+id/code"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="left|center_vertical"
android:text="@string/weibosdk_demo_step_to_obtain_code" />
<Button
android:id="@+id/auth_code"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:text="@string/weibosdk_demo_step_to_obtain_token" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/weibosdk_demo_code_text_hint"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/code_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/weibosdk_demo_token_text_hint"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/token_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
布局文件非常简单 就是简单的两个button组件和两个TextView用于显示获取到的code和Token值以及授权的时间expire
至此已经详细讲解了微博登录时的auth2.0认证的实现。
最后附上本文中所提到的sinasdk-core.jar包的下载地址: