新浪微博开放平台SSO授权上线
- - 微博之博作为一名普通微博用户,在手机上使用 新浪微博客户端,已经输入过自己的帐号及密码,是否期待手机上的第三方应用如360安全浏览器、唱吧等,可以识别当前的微博帐号,而不需要重新输入账号密码进行登陆. 近日,新浪微博开放平台 SSO授权的正式上线,帮助用户实现了这一愿望. SSO英文全称Single Sign On(单点登录),意指用户只需登录一次,就可以访问相互信任的其他应用系统.
很多人不会使用第三方应用,特写此篇使用下第三方应用:代码具体如下:
【ConstantS.java】
public interface ConstantS { // 应用的key 请到官方申请正式的appkey替换APP_KEY public static final String APP_KEY = "2045436852"; // 替换为开发者REDIRECT_URL public static final String REDIRECT_URL = "http://www.sina.com"; // 新支持scope:支持传入多个scope权限,用逗号分隔 public static final String SCOPE = "email,direct_messages_read,direct_messages_write," + "friendships_groups_read,friendships_groups_write,statuses_to_me_read," + "follow_app_official_microblog," + "invitation_write"; public static final String CLIENT_ID = "client_id"; public static final String RESPONSE_TYPE = "response_type"; public static final String USER_REDIRECT_URL = "redirect_uri"; public static final String DISPLAY = "display"; public static final String USER_SCOPE = "scope"; public static final String PACKAGE_NAME = "packagename"; public static final String KEY_HASH = "key_hash"; }
import java.text.SimpleDateFormat; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; import android.widget.Toast; import com.weibo.sdk.android.Oauth2AccessToken; import com.weibo.sdk.android.Weibo; import com.weibo.sdk.android.WeiboAuthListener; import com.weibo.sdk.android.WeiboDialogError; import com.weibo.sdk.android.WeiboException; import com.weibo.sdk.android.sso.SsoHandler; import com.weibo.sdk.android.util.AccessTokenKeeper; public class MainActivity extends Activity { /** 显示认证后的信息,如AccessToken */ private TextView mText; /** 微博API接口类,提供登陆等功能 */ private Weibo mWeibo; /** 封装了 "access_token","expires_in","refresh_token",并提供了他们的管理功能 */ private Oauth2AccessToken mAccessToken; /** 注意:SsoHandler 仅当sdk支持sso时有效 */ private SsoHandler mSsoHandler; private Intent intent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mText = (TextView) findViewById(R.id.show); mWeibo = Weibo.getInstance(ConstantS.APP_KEY, ConstantS.REDIRECT_URL, ConstantS.SCOPE); // 触发sso测试button findViewById(R.id.share).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), ShareActivity.class); intent.putExtra("id", R.id.share); startActivity(intent); } }); // 触发sso测试button findViewById(R.id.sso).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mSsoHandler = new SsoHandler(MainActivity.this, mWeibo); mSsoHandler.authorize(new AuthDialogListener(), null); } }); // 从 SharedPreferences 中读取上次已保存好 AccessToken 等信息, // 第一次启动本应用,AccessToken 不可用 mAccessToken = AccessTokenKeeper.readAccessToken(this); if (mAccessToken.isSessionValid()) { String date = new java.text.SimpleDateFormat("yyyy/MM/dd hh:mm:ss") .format(new java.util.Date(mAccessToken.getExpiresTime())); mText.setText("access_token 仍在有效期内,无需再次登录: \naccess_token:" + mAccessToken.getToken() + "\n有效期:" + date); } else { mText.setText("使用SSO登录前,请检查手机上是否已经安装新浪微博客户端," + "目前仅3.0.0及以上微博客户端版本支持SSO;如果未安装,将自动转为Oauth2.0进行认证"); } } /** * 微博认证授权回调类。 1. SSO登陆时,需要在{@link #onActivityResult} * 中调用mSsoHandler.authorizeCallBack后, 该回调才会被执行。 2. 非SSO登陆时,当授权后,就会被执行。 * 当授权成功后,请保存该access_token、expires_in等信息到SharedPreferences中。 */ class AuthDialogListener implements WeiboAuthListener { @Override public void onComplete(Bundle values) { String token = values.getString("access_token"); String expires_in = values.getString("expires_in"); mAccessToken = new Oauth2AccessToken(token, expires_in); if (mAccessToken.isSessionValid()) { String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss") .format(new java.util.Date(mAccessToken .getExpiresTime())); mText.setText("认证成功: \r\n access_token: " + token + "\r\n" + "expires_in: " + expires_in + "\r\n有效期:" + date); AccessTokenKeeper.keepAccessToken(MainActivity.this, mAccessToken); Toast.makeText(MainActivity.this, "认证成功", Toast.LENGTH_SHORT) .show(); } } @Override public void onError(WeiboDialogError e) { Toast.makeText(getApplicationContext(), "Auth error : " + e.getMessage(), Toast.LENGTH_LONG).show(); } @Override public void onCancel() { Toast.makeText(getApplicationContext(), "Auth cancel", Toast.LENGTH_LONG).show(); } @Override public void onWeiboException(WeiboException e) { Toast.makeText(getApplicationContext(), "Auth exception : " + e.getMessage(), Toast.LENGTH_LONG) .show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // SSO 授权回调 // 重要:发起 SSO 登陆的Activity必须重写onActivityResult if (mSsoHandler != null) { mSsoHandler.authorizeCallBack(requestCode, resultCode, data); } } }
import android.app.Activity; import android.content.Intent; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.sina.weibo.sdk.WeiboSDK; import com.sina.weibo.sdk.api.BaseResponse; import com.sina.weibo.sdk.api.IWeiboAPI; import com.sina.weibo.sdk.api.IWeiboHandler; import com.sina.weibo.sdk.api.ImageObject; import com.sina.weibo.sdk.api.SendMessageToWeiboRequest; import com.sina.weibo.sdk.api.SendMultiMessageToWeiboRequest; import com.sina.weibo.sdk.api.TextObject; import com.sina.weibo.sdk.api.WeiboMessage; import com.sina.weibo.sdk.api.WeiboMultiMessage; /** * 该Activity演示了第三方应用如何发送请求消息给微博客户端。发送的内容包括文字、图片、视频、音乐等。 执行流程: 从本应用->微博->本应用 */ public class ShareActivity extends Activity implements OnClickListener, IWeiboHandler.Response { /** 微博OpenAPI访问入口 */ IWeiboAPI mWeiboAPI = null; // UI元素列表 /** 分享文本 */ private TextView mTitle; /** 分享图片 */ private ImageView mImage; /** 分享按钮 */ private Button mSharedBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.share); initViews(); // 创建微博对外接口实例 mWeiboAPI = WeiboSDK.createWeiboAPI(this, ConstantS.APP_KEY); mWeiboAPI.responseListener(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); mWeiboAPI.responseListener(intent, this); } /** * 从本应用->微博->本应用 接收响应数据,该方法被调用。 注意:确保{@link #onCreate(Bundle)} 与 * {@link #onNewIntent(Intent)}中, 调用 mWeiboAPI.responseListener(intent, * this) */ @Override public void onResponse(BaseResponse baseResp) { switch (baseResp.errCode) { case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_OK: Toast.makeText(this, "成功!!", Toast.LENGTH_LONG).show(); break; case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_CANCEL: Toast.makeText(this, "用户取消!!", Toast.LENGTH_LONG).show(); break; case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_FAIL: Toast.makeText(this, baseResp.errMsg + ":失败!!", Toast.LENGTH_LONG) .show(); break; } } /** * 用户点击分享按钮,唤起微博客户端进行分享。 */ @Override public void onClick(View v) { if (R.id.sharedBtn == v.getId()) { mWeiboAPI.registerApp(); reqMsg(true, true, false, false, false, false); } } private void initViews() { mSharedBtn = (Button) findViewById(R.id.sharedBtn); mSharedBtn.setOnClickListener(this); mTitle = (TextView) findViewById(R.id.titleText); mImage = (ImageView) findViewById(R.id.image); } private void reqMsg(boolean hasText, boolean hasImage, boolean hasWebpage, boolean hasMusic, boolean hasVedio, boolean hasVoice) { if (mWeiboAPI.isWeiboAppSupportAPI()) { Toast.makeText(this, "当前微博版本支持SDK分享", Toast.LENGTH_SHORT).show(); int supportApi = mWeiboAPI.getWeiboAppSupportAPI(); if (supportApi >= 10351) { Toast.makeText(this, "当前微博版本支持多条消息,Voice消息分享", Toast.LENGTH_SHORT).show(); reqMultiMsg(hasText, hasImage, hasWebpage, hasMusic, hasVedio, hasVoice); } else { Toast.makeText(this, "当前微博版本只支持单条消息分享", Toast.LENGTH_SHORT) .show(); reqSingleMsg(hasText, hasImage, hasWebpage, hasMusic, hasVedio/* * , * hasVoice */); } } else { Toast.makeText(this, "当前微博版本不支持SDK分享", Toast.LENGTH_SHORT).show(); } } /** * 第三方应用发送请求消息到微博,唤起微博分享界面。 注意:当isWeiboAppSupportAPI() >= 10351 * 时,支持同时分享多条消息, 同时可以分享文本、图片以及其它媒体资源(网页、音乐、视频、声音中的一种), 并且支持Voice消息。 * * @param hasText * 分享的内容是否有文本 * @param hasImage * 分享的内容是否有图片 * @param hasWebpage * 分享的内容是否有网页 * @param hasMusic * 分享的内容是否有音乐 * @param hasVideo * 分享的内容是否有视频 * @param hasVoice * 分享的内容是否有声音 */ private void reqMultiMsg(boolean hasText, boolean hasImage, boolean hasWebpage, boolean hasMusic, boolean hasVideo, boolean hasVoice) { // 1. 初始化微博的分享消息 WeiboMultiMessage weiboMessage = new WeiboMultiMessage(); if (hasText) { weiboMessage.textObject = getTextObj(); } if (hasImage) { weiboMessage.imageObject = getImageObj(); } // 2. 初始化从第三方到微博的消息请求 SendMultiMessageToWeiboRequest req = new SendMultiMessageToWeiboRequest(); // 用transaction唯一标识一个请求 req.transaction = String.valueOf(System.currentTimeMillis()); req.multiMessage = weiboMessage; // 3. 发送请求消息到微博,唤起微博分享界面 mWeiboAPI.sendRequest(this, req); } /** * 第三方应用发送请求消息到微博,唤起微博分享界面。 当isWeiboAppSupportAPI() < 10351 只支持分享单条消息,即 * 文本、图片、网页、音乐、视频中的一种,不支持Voice消息。 * * @param hasText * 分享的内容是否有文本 * @param hasImage * 分享的内容是否有图片 * @param hasWebpage * 分享的内容是否有网页 * @param hasMusic * 分享的内容是否有音乐 * @param hasVideo * 分享的内容是否有视频 */ private void reqSingleMsg(boolean hasText, boolean hasImage, boolean hasWebpage, boolean hasMusic, boolean hasVideo/* * , boolean * hasVoice */) { // 1. 初始化微博的分享消息 // 用户可以分享文本、图片、网页、音乐、视频中的一种 WeiboMessage weiboMessage = new WeiboMessage(); if (hasText) { weiboMessage.mediaObject = getTextObj(); } if (hasImage) { weiboMessage.mediaObject = getImageObj(); } // 2. 初始化从第三方到微博的消息请求 SendMessageToWeiboRequest req = new SendMessageToWeiboRequest(); // 用transaction唯一标识一个请求 req.transaction = String.valueOf(System.currentTimeMillis()); req.message = weiboMessage; // 3. 发送请求消息到微博,唤起微博分享界面 mWeiboAPI.sendRequest(this, req); } /** * 文本消息构造方法。 * * @return 文本消息对象。 */ private TextObject getTextObj() { TextObject textObject = new TextObject(); textObject.text = mTitle.getText().toString(); return textObject; } /** * 图片消息构造方法。 * * @return 图片消息对象。 */ private ImageObject getImageObj() { ImageObject imageObject = new ImageObject(); BitmapDrawable bitmapDrawable = (BitmapDrawable) mImage.getDrawable(); imageObject.setImageObject(bitmapDrawable.getBitmap()); return imageObject; } }