• 新浪微博Oauth2.0授权认证及SDK、API的使用(Android)


    ----------------------------------------------------------------------------------------------

    [版权申明:本文系作者原创,转载请注明出处
    文章出处:http://blog.csdn.net/sdksdk0/article/details/51939853
    作者:朱培      ID:sdksdk0      邮箱: zhupei@tianfang1314.cn   

    --------------------------------------------------------------------------------------------

    本文主要介绍新浪微博客户端的api接入,实现第三方授权登录功能,以及api的调用。要求亲自动手进行实际操作,学会基本的授权认证机制和常用API的调用。这里主要是一个安卓端的应用,文末提供源码下载。

    一、微博开发者平台的使用

    新浪微博这里主要是介绍使用新浪微博的开发者平台。想要做一个基于微博登陆或者其他一系列操作的,我们先要登陆他们的官网进行注册使用,首先是要注册成为一个开发者。http://open.weibo.com/。微博开放平台为移动应用提供了便捷的合作模式,满足了多元化移动终端用户随时随地快速登录、分享信息的需求,助力实现移动Apps、健康设备、智能家居,车载等多类型终端的社会化接入。

    1、注册登录之后,进入“微连接”->"移动应用"->创建应用。然后自己进行设置就可以了。

    2、创建好之后,进入“我的应用” ->应用信息->基本信息"进行设置。这这里就设置你的应用基本信息就可以了。填好你的包名之后,需要下载里面的sdk文件。

    3、在这里下载  安卓的sdk文件。https://github.com/sinaweibosdk/weibo_android_sdk

    在这里面找到一个app_signatures.apk,然后安装到你手机上面去,点击运行,把你的包名输入进去之后,就会产生一段序列号,然后把这个序列号复制到前面提到的这个开发者平台中的---“Android签名包名信息”->Android签名.  最后就会生成App Key和App Secret。这两个东西我们稍后会用到。

     

    4、OAuth2.0 授权设置。点击“高级信息”  ->授权设置,设置授权回调页和取消授权回调页。我这里设置的是http://www.tianfang1314.cn/。这个地方你可以自行设置。

     

    最后:到这里基本的设置工作就完成了。我们最后需要从这里得到的是pp Key和App Secret、以及回调页的网址

    二、Oauth2.0授权认证授权机制

    n新浪微博Android SDK为开发者提供了Oauth2.0授权认证,并集成SSO登录功能,使第三方应用无需了解复杂的验证机制即可进行授权登录操作,并提供微博分享功能,第三方应用可直接通过微博客户端进行分享。新浪微博Android SDK的有三种授权方式。
     
     

    Oauth2.0协议:

    允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

     

    三、Android Studio中使用微博SDK

    首先导入新浪微博的sdk文件:千万不要直接把库拷贝进项目文件夹中,这样可能会出现各种其他不知名的错误,建议通过Import Module方式一步步导入库文件。然后在file->project structure->dependencies->3Model dependency中选择Weibo库就可以了.此时库已成功导入。

    布局文件我这里就不写出来了,需要的可以去我文末提供的地址进行下载。这里主要说一下如何使用。首先我们需要新建一个utils包,用来存放一些授权的信息。这几个文件可以直接在下载的SDK的官方demo中找到。其主要内容为:

     

    AccessTokenKeeper.java

    public class AccessTokenKeeper {
    	private static final String PREFERENCES = "sina";
    	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";
    
    	public static void writeAccessToken(Context context, Oauth2AccessToken token) {
    		if (context == null || token == null) {
    			return;
    		}
    		SharedPreferences preferences = context.getSharedPreferences(
    				PREFERENCES, context.MODE_APPEND);
    		Editor editor = preferences.edit();
    		editor.putString(KEY_UID, token.getUid());
    		editor.putString(KEY_ACCESS_TOKEN, token.getToken());
    		editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
    		editor.commit();
    	}
    
    	public static Oauth2AccessToken readAccessToken(Context context) {
    		if (null == context) {
    			return null;
    		}
    
    		Oauth2AccessToken token = new Oauth2AccessToken();
    		SharedPreferences pref = context.getSharedPreferences(PREFERENCES,
    				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;
    	}
    
    	public static void clear(Context context) {
    		if (null == context) {
    			return;
    		}
    
    		SharedPreferences pref = context.getSharedPreferences(PREFERENCES,
    				Context.MODE_APPEND);
    		Editor editor = pref.edit();
    		editor.clear();
    		editor.commit();
    	}
    
    }
    

     

    Constants.java.

    这里要注意一下,我们前面在开发者平台中拿到的appkey和appsecret要拿到这里来使用。这里替换一下你的。还有就是那个回调页,也需要设置一下,记住:回调页的网址不要写错,要和你原来配置时是一样的,错一个字母都不行的哦!

    public class Constants {
    	public static final String APP_KEY = "换成你的appkey";
    	public static final String App_SECRET = "换成你的app_secret";
    
    	/**
    	 * 当前 DEMO 应用的回调页,第三方应用可以使用自己的回调页。
    	 * 建议使用默认回调页:https://api.weibo.com/oauth2/default.html
    	 */
    	public static final String REDIRECT_URL = "http://www.tianfang1314.cn/";
    
    	/**
    	 * WeiboSDKDemo 应用对应的权限,第三方开发者一般不需要这么多,可直接设置成空即可。 详情请查看 Demo 中对应的注释。
    	 */
    	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 user_show = "https://api.weibo.com/2/users/show.json?uid={0}&access_token={1}";
    	public static final String public_timeline = "https://api.weibo.com/2/statuses/public_timeline.json?access_token={0}";
    	public static final String friends_timeline = "https://api.weibo.com/2/statuses/friends_timeline.json?access_token={0}";
    	public static final String home_timeline = "https://api.weibo.com/2/statuses/home_timeline.json?count=20&access_token={0}";
    	public static final String bilateral_timeline = "https://api.weibo.com/2/statuses/bilateral_timeline.json?count=20&access_token={0}";
    	public static final String repost = "https://api.weibo.com/2/statuses/repost.json";
    	public static final String updata = "https://api.weibo.com/2/statuses/update.json";
    	public static final String comment_show = "https://api.weibo.com/2/comments/show.json?access_token={0}";
    	public static final String comment_create = "https://api.weibo.com/2/comments/create.json";
    	public static final String friendships_destroy = "https://api.weibo.com/2/friendships/destroy.json";
    	public static final String friendships_create = "https://api.weibo.com/2/friendships/create.json";
    	public static final String followers = "https://api.weibo.com/2/friendships/followers.json";
    	public static final String user_timeline = "https://api.weibo.com/2/statuses/user_timeline.json";
    	public static final String delete = "https://api.weibo.com/2/statuses/destroy.json";
    	public static final String friendship_friends = "https://api.weibo.com/2/friendships/friends.json";
    	public static final String replay = "https://api.weibo.com/2/comments/reply.json";
    	public static final String bilateral_timeline2 = "https://api.weibo.com/2/statuses/bilateral_timeline.json";
    	public static final String mentions = "https://api.weibo.com/2/statuses/mentions.json";
    	public static final String weekly = "https://api.weibo.com/2/trends/weekly.json";
    	public static final String daily = "https://api.weibo.com/2/trends/daily.json";
    	public static final String hourly = "https://api.weibo.com/2/trends/hourly.json";
    	public static final String users = "https://api.weibo.com/2/search/suggestions/users.json";
    	public static final String upload = "https://upload.api.weibo.com/2/statuses/upload.json";
    	public static final String comment_mentions = "https://api.weibo.com/2/comments/mentions.json";
    }
    


    HttpUtils.java

     

    public class HttpUtils {
    
    	/**
    	 * 通过url地址返回一个输入流
    	 *
    	 * @param url
    	 *            地址
    	 * @return 输入流
    	 */
    	public static InputStream getInputStream(String url) {
    		URL home_url = null;
    
    		InputStream input = null;
    
    		HttpURLConnection conn = null;
    
    		try {
    			home_url = new URL(url);
    
    			conn = (HttpURLConnection) home_url.openConnection();
    
    			conn.setRequestMethod("GET");
    
    			conn.setConnectTimeout(5000);
    
    			conn.connect();
    
    			input = conn.getInputStream();
    
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    
    		return input;
    
    	}
    
    
    	/**
    	 * 返回字符串
    	 *
    	 * @param url
    	 * @return
    	 */
    	public static String getStringByStream(String url) {
    
    		StringBuilder sb = null;
    		BufferedReader br = null;
    
    		InputStream input = getInputStream(url);
    
    
    		if (input != null) {
    			br = new BufferedReader(new InputStreamReader(input));
    
    			String line = null;
    			sb = new StringBuilder();
    			try {
    				while ((line = br.readLine()) != null) {
    					sb.append(line);
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    
    		}else{
    			sb = new StringBuilder("");
    		}
    
    		return sb.toString();
    
    	}
    
    }


    接下来我们就需要来写界面的java代码了.

    登陆微博

    LoginActivity.java

    public class LoginActivity extends Activity {
    
    	AuthInfo mauthInfo;
    
    	SsoHandler ssoHandler;
    
    	Oauth2AccessToken accessToken;
    
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		setContentView(R.layout.activity_login);
    
    		initDatas();
    	}
    
    	/**
    	 * 数据初始化
    	 */
    	private void initDatas() {
    		// 上下文
    		mauthInfo = new AuthInfo(LoginActivity.this, Constants.APP_KEY, Constants.REDIRECT_URL,
    				Constants.SCOPE);
    		ssoHandler = new SsoHandler(LoginActivity.this, mauthInfo);
    
    		ssoHandler.authorize(new WeiboAuthListener() {
    
    			//认证失败
    			@Override
    			public void onWeiboException(WeiboException arg0) {
    
    				Toast.makeText(LoginActivity.this, "认证失败"+arg0, Toast.LENGTH_SHORT).show();
    			}
    
    			//认证成功的
    			@Override
    			public void onComplete(Bundle arg0) {
    
    				accessToken = Oauth2AccessToken.parseAccessToken(arg0);
    
    				//验证我们的令牌是否有效
    				if(accessToken.isSessionValid()){
    					AccessTokenKeeper.writeAccessToken(LoginActivity.this, accessToken);
    					Toast.makeText(LoginActivity.this, "认证成功", Toast.LENGTH_SHORT).show();
    				}
    
    
    			}
    
    			//取消认证的
    			@Override
    			public void onCancel() {
    				// TODO Auto-generated method stub
    				Toast.makeText(LoginActivity.this, "取消认证", Toast.LENGTH_SHORT).show();
    
    			}
    		});
    
    	}
    
    }


    发送微博:

    public class SendWeibo extends Activity {
    
    	//令牌
    	Oauth2AccessToken accessToken;
    
    	StatusesAPI statusesApi;
    
    	private EditText et_weibo;
    
    	private Button btn_sendweibo;
    
    
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		setContentView(R.layout.activity_sendweibo);
    
    		initDatas();
    
    		initViews();
    
    
    	}
    
    	private void initViews() {
    
    		et_weibo = (EditText)findViewById(R.id.et_weibo);
    
    		btn_sendweibo =(Button)findViewById(R.id.btn_sendweibo);
    
    
    		btn_sendweibo.setOnClickListener(new OnClickListener() {
    
    				@Override
    				public void onClick(View v) {
    				String weibo = et_weibo.getText().toString();
    
    				if(!TextUtils.isEmpty(weibo)){
    
    					statusesApi.update(weibo, null, null, new RequestListener() {
    
    						@Override
    						public void onWeiboException(WeiboException arg0) {
    							Toast.makeText(SendWeibo.this, "发送失败", Toast.LENGTH_SHORT).show();
    						}
    
    						@Override
    						public void onComplete(String arg0) {
    
    							Toast.makeText(SendWeibo.this, "发送成功", Toast.LENGTH_SHORT).show();
    						}
    					});
    
    				}
    
    			}
    		});
    
    	}
    
    	private void initDatas(){
    		accessToken = AccessTokenKeeper.readAccessToken(SendWeibo.this);
    
    		statusesApi = new StatusesAPI(SendWeibo.this, Constants.APP_KEY, accessToken);
    
    	}
    
    
    }



    主界面调用:

    public class MainActivity extends Activity {
    
        private static final String TAG = MainActivity.class.getSimpleName();
    
    
        private static final DemoInfo[] demos = {
                new DemoInfo("登录微博","first",LoginActivity.class),
                new DemoInfo("发送微博","second",SendWeibo.class)
        };
    
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            TextView text = (TextView) findViewById(R.id.text_Info);
            text.setTextColor(Color.RED);
            text.setText("新浪微博实例");
            ListView mListView = (ListView) findViewById(R.id.listView);
            // 添加ListItem,设置事件响应
            mListView.setAdapter(new DemoListAdapter());
            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                public void onItemClick(AdapterView<?> arg0, View v, int index,
                                        long arg3) {
                    onListItemClick(index);
                }
            });
        }
    
    
        public void onListItemClick(int index) {
            Intent intent = null;
            intent = new Intent(MainActivity.this, demos[index].demoClass);
    
            Log.d(TAG, "itemClick()");
            this.startActivity(intent);
        }
    
    
        /**
         * demo列表适配器
         *
         *
         */
        private class DemoListAdapter extends BaseAdapter {
            public DemoListAdapter() {
                super();
            }
    
            @Override
            public View getView(int index, View convertView, ViewGroup parent) {
                convertView = View.inflate(MainActivity.this,
                        R.layout.demo_info_item, null);
    
                TextView title = (TextView) convertView.findViewById(R.id.title);
                TextView desc = (TextView) convertView.findViewById(R.id.desc);
                title.setText(demos[index].title);
                desc.setText(demos[index].desc);
                if (index >= 16) {
                    title.setTextColor(Color.YELLOW);
                }
                return convertView;
            }
    
            @Override
            public int getCount() {
                return demos.length;
            }
    
            @Override
            public Object getItem(int index) {
                return demos[index];
            }
    
            @Override
            public long getItemId(int id) {
                return id;
            }
        }
    
    
        /**
         * item的信息
         *
         */
        private static class DemoInfo {
            private final String title;
            private final String desc;
            private final Class<? extends android.app.Activity> demoClass;
    
            public DemoInfo(String title, String desc,
                            Class<? extends android.app.Activity> demoClass) {
                this.title = title;
                this.desc = desc;
                this.demoClass = demoClass;
            }
        }
    }



    最后的最后。我们需要时清单文件中对权限进行配置。

     <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <activity android:name="com.zhilinghui.weibo.ui.LoginActivity" >
            </activity>
    
            <activity android:name="com.zhilinghui.weibo.ui.SendWeibo" >
            </activity>
    
    
            <!-- 必须注册在微博授权,分享微博时候用到 -->
            <activity
                android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"
                android:configChanges="keyboardHidden|orientation"
                android:exported="false"
                android:windowSoftInputMode="adjustResize" >
            </activity>
    


    到这里,我们就全部开发完了,可以直接使用微博进行登录了,还可以有发送微博的功能。

     

    总结:这个案例其实总的来说非常简单,就是有一些细节的部分还需要进一步的处理。对于各种奇奇怪怪的小bug需要时间去调试,需要很多的耐心。在注册新浪微博开发者平台的时候,对于应用的设置和包的签名,页面回调等都需要去处理,真的耐心和细心非常重要。共勉!

    如有疑问欢迎交流:zhupei@tianfang1314.cn   (邮箱)



    源码下载:http://download.csdn.net/detail/sdksdk0/9578861

     https://github.com/sdksdk0/SinaWeiboDemo

  • 相关阅读:
    shiro中 UnknownAccountException
    shiro Filter--拦截器
    java构造器执行顺序一个有趣的简单实例
    Java Serializable接口(序列化)理解及自定义序列化
    js中绑定事件处理函数,使用event以及传递额外数据
    js中的this
    jQuery + ashx 实现图片按比例预览、异步上传及显示
    asp.net中的参数传递:Context.Handler 的用法
    javascript 对象详解
    ashx 文件的运用
  • 原文地址:https://www.cnblogs.com/sdksdk0/p/6060038.html
Copyright © 2020-2023  润新知