接上篇博文提到了
android新浪微博Oauth2.0认证以及登录
http://blog.csdn.net/geniuseoe2012/article/details/7727564
也提到了写SDK的这家伙很坑爹的把界面元素也添到了SDK里面
而我们则希望SDK提供的是纯接口的东东
之前看到网上不少关于webview实现新浪微博认证,思路都是通过WebView显示的html代码然后从中提取出授权码,不过那样界面会跳转到授权码显示页面,界面看起来不是很和谐,而我们直接使用SDK里的那种方式就可以很方便的实现我们想要的效果
为此在下特意研究了下SDK里认证界面的具体实现,然后将其中的代码提取出来,仿其实现方式用我们自己的webview来实现微博的认证过程,这样我们就不必再依赖SDK工程而可以直接将SRC打成jar包导入了,下面先看工程目录图:
Com.weibo.net这个包就是把SDK里的代码copy过来,然后把一些不相干的类给干掉了,同时屏蔽掉一些接口,本例没有把它们打成jar包,为的是方便大家看到源码
同时SDK里的源码有个小错误:
就是AsyncWeiboRunner类下的request方法
public void request(final Context context, final String url, final WeiboParameters params, final String httpMethod, final RequestListener listener){ new Thread(){ @Override public void run() { try { String resp = mWeibo.request(context, url, params, httpMethod, mWeibo.getAccessToken()); listener.onComplete(resp); } catch (WeiboException e) { listener.onError(e); } } }.run(); }
尼玛直接run难怪会阻塞UI线程,改成start就OK了。
下面着重讲讲webview这个页面认证的实现原理
且看 WeiboWebViewClient 这个类
private class WeiboWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { MyDebug.print("WeiboWebViewClient", "shouldOverrideUrlLoading url = " + url); showProgress(); view.loadUrl(url); return super.shouldOverrideUrlLoading(view, url); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { MyDebug.printErr("WeiboWebViewClient", "onReceivedError failingUrl = " + failingUrl); super.onReceivedError(view, errorCode, description, failingUrl); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { MyDebug.print("WeiboWebViewClient", "onPageStarted url = " + url + "\nthreadid = " + Thread.currentThread().getId()); showProgress(); if (url.startsWith(mWeiboManager.getRedictUrl())) { handleRedirectUrl(view, url, WebViewActivity.this); view.stopLoading(); return; } super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { MyDebug.print("WeiboWebViewClient", "onPageFinished url = " + url); hideProgress(); super.onPageFinished(view, url); } private boolean handleRedirectUrl(WebView view, String url, IWeiboClientListener listener) { Bundle values = Utility.parseUrl(url); String error = values.getString("error"); String error_code = values.getString("error_code"); MyDebug.print("handleRedirectUrl", "error = " + error + "\n error_code = " + error_code); if (error == null && error_code == null) { listener.onComplete(values); }else if (error.equals("access_denied")) { listener.onCancel(); }else{ WeiboException weiboException = new WeiboException(error, Integer.parseInt(error_code)); listener.onWeiboException(weiboException); } return false; } }
下面这个是关键:
if (url.startsWith(mWeiboManager.getRedictUrl())) { handleRedirectUrl(view, url, WebViewActivity.this); view.stopLoading(); return; }
也就是我们进入授权页面点击授权的时候,页面最终会去载入我们先前传入的URL回调地址(该回调地址作为前缀),此时我们只要从该URL里去解析我们想要的东西即可
如何解析URL在sdk里有提供相应方法,即Utility.parseUrl(url);在handleRedirectUrl里根据解析得到的结果调用监听器相应接口即可,我们再看看监听器onComplete里的实现
public void onComplete(Bundle values) { // TODO Auto-generated method stub CookieSyncManager.getInstance().sync(); String access_token = values.getString("access_token"); String expires_in = values.getString("expires_in"); String remind_in = values.getString("remind_in"); String uid = values.getString("uid"); MyDebug.print("onComplete", "access_token = " + access_token + "\nexpires_in = " + expires_in); AuthoSharePreference.putToken(this, access_token); AuthoSharePreference.putExpires(this, expires_in); AuthoSharePreference.putRemind(this, remind_in); AuthoSharePreference.putUid(this, uid); AccessToken accessToken = new AccessToken(access_token, WeiboConstParam.CONSUMER_SECRET); mWeiboManager.setAccessToaken(accessToken); setResult(RESULT_OK); finish(); }
怎么样,是不是跟官方的那个例子很接近了,拿到access_token我们就可以为所欲为了
截图就不贴了,跟前篇博文的效果差不多,只不过认证页面放在了activity里而不在一个dialog而已
下面附上源码工程:
http://download.csdn.net/detail/geniuseoe2012/4441971
老规矩,WeiboConstParam.java里的key值等等参数修改成自己的值就可以了
public interface WeiboConstParam { String CONSUMER_KEY = "-----------"; // appkey String CONSUMER_SECRET = "------------"; // secret String REDIRECT_URL = "---------------"; // url回调地址 }
本例发微博部分只能发纯文本,以后再教大家如何使用更多微博API,
敬请留意窝的博客更新