android 新浪微博Oauth2.0认证
首先不得不说,自己犯了一个比较窝囊的错误,不过也不能完全怪我,因为大家都知道,新浪微博Oauth2.0提供的jar包,好家伙2M多,谁看谁都不想用,才使得我去研究1.0的使用,研究好久,终于实现可用了,变态的新浪最新说要停止1.0接口的调用,害的我不得不更改了,想想也是,人家升级就是为了好用嘛。好了不抱怨了,因为新浪Oauth2.0比1.0方便多了,也好用多了,在这里我简单说明一下:
首先我不喜欢新浪提供的那样加jar包的方式,因此就把他们的源码整合到我的应用中,看起来也比较直观.其实很简单,就是把com.weibo.net包copy到自己项目里,把Bug调理好就OK了.这里不多说了,下面讲下如何使用:
代码片段:
weibo = Weibo.getInstance(); weibo.setupConsumerConfig(consumer_key, consumer_secret); weibo.setRedirectUrl(mRedirectUrl); // 认证 weibo.authorize(MainActivity.this, new MyWeiboDialogListener());
class MyWeiboDialogListener implements WeiboDialogListener { @Override public void onComplete(Bundle values) { /*** * 保存token and expires_in */ String token = values.getString("access_token");// 获取access_token editor = preferences.edit(); editor.putString("token", token); editor.commit(); Toast.makeText(MainActivity.this, token, 1000).show(); // String expires_in = values.getString("expires_in");// 到期时间 AccessToken accessToken = new AccessToken(token, consumer_secret); // accessToken.setExpiresIn(expires_in); Intent intent = new Intent(); intent.setClass(MainActivity.this, MainActivity.class); startActivity(intent); } @Override public void onWeiboException(WeiboException e) { } @Override public void onError(DialogError e) { } @Override public void onCancel() { } }上面代码我们只需要在接口中保存token,expires_in值,(以便我们以后不用再次Oauth认证) ,但是发现我们只保存token就可以实现,expires_in这个值我想只是个形式,如果到期的话token就会失效,这个时候应该需要从新认证,获取新的token值,(这里占时这么说,我没有调查过,有时间好好研究下在结论.别介意)
发送调用:
if (token == null || token.equals("")) { Toast.makeText(MainActivity.this, "请先Oauth认证", 1000).show(); } else { Utility.setAuthorization(new Oauth2AccessTokenHeader()); // 这一步不能省. AccessToken accessToken = new AccessToken(token, consumer_secret); Weibo.getInstance().setAccessToken(accessToken); update(weibo.getInstance(), weibo.getAppKey(), editText .getText().toString(), "", ""); /*** * 获取相应接口数据 */ // try { // getPublicTimeline(weibo.getInstance()); // } catch (MalformedURLException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } }
官方源码:
private void authorize(Activity activity, String[] permissions, int activityCode, final WeiboDialogListener listener) { Utility.setAuthorization(new Oauth2AccessTokenHeader()); boolean singleSignOnStarted = false; mAuthDialogListener = listener; // Prefer single sign-on, where available. if (activityCode >= 0) { singleSignOnStarted = startSingleSignOn(activity, APP_KEY, permissions, activityCode); } // Otherwise fall back to traditional dialog. if (!singleSignOnStarted) { startDialogAuth(activity, permissions); } }
Utility.setAuthorization(new Oauth2AccessTokenHeader());
</span>
这句话要在你创建AccessToken之前执行,记住就行了,我水平也不高.
这样我们就实现了发表微博.
最后还要说明一点,在我们应用中直接使用他们的dialog认证,有个不足之处.
其实也没什么,就是用起来不方便,动不动就会遮盖这个view,因为官方提供的是一个Dialog,所以我们不能用
android:windowSoftInputMode="adjustPan|stateAlwaysVisible"
但是我们可以在代码中实现,在com.weibo.net.WeiboDialog.java中oncreate中加入:
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);这样我们就不会在遮盖我的iew了,效果如下:
你看,这样就不影响了,对了,我对dialog自己进行了处理,大家也可以根据自己的眼光,进行处理.
上面简单就介绍到这里,因为自我感觉不灵活,下面我们来看几个应用视图:
看起来很友好吧,因此就要创建自己的webview的Activity。
下面我介绍下怎么实现:
创建MyWebViewActivity.java
package com.jj.sina; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.graphics.Bitmap; import android.net.Uri; import android.net.http.SslError; import android.os.Bundle; import android.util.Log; import android.view.View; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.LinearLayout; import android.widget.Toast; import com.weibo.net.AccessToken; import com.weibo.net.DialogError; import com.weibo.net.Utility; import com.weibo.net.Weibo; import com.weibo.net.WeiboDialogListener; import com.weibo.net.WeiboException; /*** * 自定义webview(Oauth认证) * * @author zhangjia * */ public class MyWebViewActivity extends Activity implements WeiboDialogListener { private final String TAG = "jjhappyforever"; private WebView mWebView; private WeiboDialogListener mListener; private LinearLayout linearLayout; public void InitWebView() { linearLayout = (LinearLayout) findViewById(R.id.ll_webview); mWebView = (WebView) findViewById(R.id.mywebview); mWebView.setVerticalScrollBarEnabled(false); mWebView.setHorizontalScrollBarEnabled(false); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setWebViewClient(new WeiboWebViewClient()); mWebView.loadUrl(MyWeiboManager.getOauthURL(this)); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mListener = this; setContentView(R.layout.webview); InitWebView(); } /*** * WebViewClient * * @author zhangjia * */ private class WeiboWebViewClient extends WebViewClient { /*** * 地址改变都会调用 */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.d(TAG, "Redirect URL: " + url); if (url.startsWith(Weibo.getInstance().getRedirectUrl())) { handleRedirectUrl(view, url); return true; } // launch non-dialog URLs in a full browser startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); return true; } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); mListener.onError(new DialogError(description, errorCode, failingUrl)); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d(TAG, "onPageStarted URL: " + url); // google issue. shouldOverrideUrlLoading not executed /** * 点击授权,url正确 */ if (url.startsWith(Weibo.getInstance().getRedirectUrl())) { handleRedirectUrl(view, url); view.stopLoading(); return; } super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { Log.d(TAG, "onPageFinished URL: " + url); super.onPageFinished(view, url); linearLayout.setVisibility(View.GONE); } public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } } private void handleRedirectUrl(WebView view, String url) { Bundle values = Utility.parseUrl(url); String error = values.getString("error"); String error_code = values.getString("error_code"); // 授权成功 if (error == null && error_code == null) { mListener.onComplete(values); // 拒绝失败等 } else if (error.equals("access_denied")) { mListener.onCancel(); } else { // 异常 mListener.onWeiboException(new WeiboException(error, Integer .parseInt(error_code))); } } @Override public void onComplete(Bundle values) { /*** * 在这里要save the access_token */ String token = values.getString("access_token"); SharedPreferences preferences = getSharedPreferences(MainActivity.file, 0); Editor editor = preferences.edit(); editor.putString("token", token); editor.commit(); AccessToken accessToken = new AccessToken(token, Weibo.getAppSecret()); Weibo.getInstance().setAccessToken(accessToken); setResult(RESULT_OK); finish(); } @Override public void onWeiboException(WeiboException e) { e.printStackTrace(); } @Override public void onError(DialogError e) { e.printStackTrace(); } @Override public void onCancel() { finish(); } }上面代码大部分都是copy WeiboDialog.java中的代码,只是稍微做下改变.
最重要其实有两部分:第一:怎么获取要Load的url,也就是认证界面的显示,第二:怎么获取Access_token 值,有了这个值我们才可以进行API调用
仔细看下,不难理解的.
效果图:(第一个我就不掩饰了,最上面讲的就是)
上面说的只是一个雏形,大家根据自己项目种进行调整应用就好了,这方式看起来是不是比直接调用Android新浪 jar包好看多了吧,
另外实现起来也比较灵活,新浪Oauth2.0还是瞒不错的.
转自:http://blog.csdn.net/jj120522/article/details/7928202