新浪微博客户端开发详解(二)

丌官瀚
2023-12-01
上一博文中讲解了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包的下载地址:

 类似资料: