8.腾讯微博Android客户端开发——自动获取验证码(2) .

上一节给大家讲解通过调用android系统自带的浏览器进行授权认证的,使用该种方式能很容易的完成认证,但是该种方式有个弊端,也就是如果使用第三方的浏览器如UC、天天等,输入完QQ账号信息点击“授权”后并不能再次跳转到MainActivity,导致我们的认证失败。这个问题应该是非常严重的问题,因为大部分用户都会选择第三方的浏览器作为默认的浏览器。本次给大家讲解自动获取验证码的第二种解决方案,克服上一种方法的缺陷。

第二种解决方案的主角就是我们的WevView控件,我们可以使用WebView控件来进行浏览器的操作,而不使用系统或者第三方的浏览器。

1.首先创建一个Activity,命名为WebViewActivity,该Activity种只包含一个WevView控件:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >      
  7.     <WebView     
  8.         android:id="@+id/web"  
  9.         android:layout_height="wrap_content"              
  10.         android:layout_width="wrap_content"    
  11.         />     
  12. </ScrollView>  

2.MainActivity种添加一个Button,用于启动WebViewActivity

  1. String url = "https://open.t.qq.com/cgi-bin/authorize";  
  2. Weibo weibo = new Weibo();  
  3. //修改getRequestToken()方法,返回结果为HashMap   
  4. Map<String, String> map = weibo.getRequestToken();  
  5. //获取oauth_token   
  6. oauthToken = map.get("oauth_token");  
  7. oauthTokenSecret = map.get("oauth_token_secret");  
  8. Log.i(TAG, "Request Token="+oauthToken);  
  9. Log.i(TAG, "Request Token Secret="+oauthTokenSecret);  
  10. //有些时候获取oauth_token失败,因此再次获取   
  11. if (TextUtil.isEmpty(oauthToken))  
  12. {  
  13.     getVerifier();  
  14.     return;  
  15. }  
  16. //构造请求的URL   
  17. StringBuilder urlBuilder = new StringBuilder();  
  18. urlBuilder.append(url);  
  19. urlBuilder.append("?");  
  20. urlBuilder.append("oauth_token="+oauthToken);  
  21. Intent intent = new Intent(MainActivity.this,WebViewActivity.class);  
  22. Bundle bundle=new Bundle();  
  23. bundle.putString("url", urlBuilder.toString());  
  24. intent.putExtras(bundle);  
  25. //启动WebViewActivity   
  26. startActivity(intent);  

3.WebViewActivityonCreate添加如下代码,进行浏览器的初始化:

  1. @Override  
  2. public void onCreate(Bundle savedInstanceState)  
  3. {   
  4.     super.onCreate(savedInstanceState);  
  5.     setContentView(R.layout.webview);  
  6.     WebView webView = (WebView) findViewById(R.id.web);  
  7.     Intent intent = this.getIntent();  
  8.     if (!intent.equals(null))  
  9.     {  
  10.         Bundle bundle = intent.getExtras();  
  11.         if (bundle != null)  
  12.         {  
  13.             if (bundle.containsKey("url"))  
  14.             {  
  15.                 String url = bundle.getString("url");  
  16.                 WebSettings webSettings = webView.getSettings();  
  17.                 // 支持JavScript   
  18.                 webSettings.setJavaScriptEnabled(true);  
  19.                 webSettings.setSupportZoom(true);  
  20.                 webView.requestFocus();  
  21.                 webView.loadUrl(url);  
  22.                 Log.i(TAG, "WebView Starting....");  
  23.             }  
  24.         }  
  25.     }  
  26. }  

此时如果我们运行模拟器,点击按钮启动WebViewActivity按钮后,运行效果和启动浏览器差不多,我们输入QQ账户信息,点击“授权”,如果callback为空,则Activity会显示授权码。

4.下面我们需要处理的就是如何自动获取授权码。我们知道WebView是支持JavaScript,我们可以通过JavaScript进行授权码的获去,在onCreate()方法中添加如下代码

  1. //绑定java对象到JavaScript中,这样就能在JavaScript中调用java对象,实现通信。   
  2. //这种方法第一个参数就是java对象,第二个参数表示java对象的别名,在JavaScript中使用   
  3. webView.addJavascriptInterface(new JavaScriptInterface(), "Methods");  
  4. WebViewClient client = new WebViewClient()  
  5. {  
  6.     /** 
  7.      * 回调方法,当页面加载完毕后执行 
  8.      */  
  9.     @Override  
  10.     public void onPageFinished(WebView view, String url)  
  11.     {  
  12.         Log.i(TAG, "WebView onPageFinished");  
  13.         //执行获取授权码的JavaScript   
  14.         view.loadUrl("javascript:window.Methods.getHTML('<head>'+document.getElementsByTagName('body')[0].innerHTML+'</head>');");  
  15.         super.onPageFinished(view, url);  
  16.     }  
  17. };  
  18. webView.setWebViewClient(client);  

其中JavaScriptInterface类是进行js处理的类:

  1. class JavaScriptInterface  
  2. {  
  3.     private static final String TAG = "MainActivity";  
  4.     public void getHTML(String html)  
  5.     {  
  6.         Log.i(TAG, html);  
  7.         String verifier = getVerifier(html);  
  8.         if (!TextUtil.isEmpty(verifier))  
  9.         {  
  10.             Log.i(TAG, "verifier:"+verifier);  
  11.         }  
  12.     }  
  13.   
  14.     public String getVerifier(String html)  
  15.     {  
  16.         String ret = "";  
  17.         String regEx = "授权码:[0-9]{6}";  
  18.         Pattern p = Pattern.compile(regEx);  
  19.         Matcher m = p.matcher(html);  
  20.         boolean result = m.find();  
  21.         if (result)  
  22.         {  
  23.             ret = m.group(0).substring(4);  
  24.         }  
  25.         return ret;  
  26.     }  
  27. }  

getVerifier()方法是通过正则表达式进行授权码的查找,该正则表达式是根据腾讯微博开放平台返回验证码的html源文件进行设置:

  1. <head>  
  2. <head>  
  3.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  4.     <meta name="viewport"  
  5.         content="minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0, width=device-width, user-scalable=no">  
  6.     <title></title>  
  7.     <link href="/style/oauth/mobel.css" rel="stylesheet" type="text/css">  
  8.     <style>  
  9. * {  
  10.     TEXT-DECORATION: none;  
  11. }  
  12. </style>  
  13.     <script type="text/javascript">  
  14.      var step = 0;  
  15.      var sub = 0;  
  16.      function callback(){  
  17.      }  
  18.      function cl(){  
  19.          sub = 0;  
  20.          document.getElementById('errCode').innerHTML = '你拒绝了授权此应用访问你的腾讯微博帐户,将不能使用此应用功能。';  
  21.          document.getElementById('errCode').style.display = 'block';  
  22.          var c = document.getElementById('conter');  
  23.          var ql = document.getElementById('loginform');   
  24.          c.removeChild(ql);  
  25.      }  
  26.      function changeimg(){  
  27.          var i = document.getElementById('imgVerify');  
  28.          i.src = ".jpg?d="+step;  
  29.          step++;  
  30.          /*  
  31.          i.innerHTML = '';      
  32.          window.setTimeout(function(){i.innerHTML = '<img id="imgVerify" width="130" height="53" src=".jpg" onclick="changeimg();" />';},200);  
  33.          */  
  34.      }  
  35.      function subForm(){  
  36.          var u = document.getElementById('u');  
  37.          var p = document.getElementById('p');  
  38.          if(u.value != '' && p.value!=''){  
  39.              document.getElementById('login_btn').disabledtrue;  
  40.          }else{  
  41.              return false;  
  42.          }  
  43.      }  
  44.      function subForm1(){  
  45.          var u = document.getElementById('u');  
  46.          var p = document.getElementById('p');  
  47.          var v = document.getElementById('v');  
  48.          if(u.value != '' && p.value!='' && v.value != ''){  
  49.              document.getElementById('login_btn').disabledtrue;  
  50.          }else{  
  51.              return false;  
  52.          }  
  53.      }  
  54.      </script>  
  55. </head>  
  56. <body id="body">  
  57.     <div id="header">  
  58.         <a href="http://open.t.qq.com"></a>  
  59.         <p></p>  
  60.     </div>  
  61.     <div id="headerTxt">  
  62.         <h1>  
  63.             授权使用腾讯微博帐号  
  64.         </h1>  
  65.         <cite>授权后 <span>Android开发</span> 将可访问并使用你的微博帐号</cite>  
  66.     </div>  
  67.     <div id="conter">  
  68.         <ul>  
  69.             <li>  
  70.                 授权码:240547  
  71.             </li>  
  72.         </ul>  
  73.     </div>  
  74.     <div id="info">  
  75.         <p>  
  76.             腾讯官方授权页面不允许第三方内嵌或伪造  
  77.         </p>  
  78.         <p>  
  79.             授权页面地址为http://open.t.qq.com开头。  
  80.         </p>  
  81.         <p>  
  82.             授权后,在第三方网站的活动应继续遵守《  
  83.             <a  
  84.                 href="http://ti.3g.qq.com/g/s?sid=AUV9TkhR9XziFokSOXQRypk1&r=252180&aid=pno"  
  85.                 target="_blank">腾讯QQ用户服务条款</a>》。  
  86.         </p>  
  87.     </div>  
  88.     <div id="footer">  
  89.         ? 2011 Tencent Inc.  
  90.     </div>  
  91.     <script type="text/javascript">  
  92.  var g_btrace_zhibo = new Image(1,1);  
  93.  var _u = 'http://btrace.qq.com/collect?ftime=1310183089&sIp=-1266685874&iQQ=0&sBiz=moauth&sOp=inter&iSta=0&iTy=424&iFlow=0&t=3&c=0&oa=1200b4a5a24f45509478a4a809d75495&r=7';  
  94.  g_btrace_zhibo.src = _u;  
  95.  </script>  
  96. </body>  
  97. </head>  

至此我们就完成了如何通过WebView控件获取验证码的方法,解决了上一节的缺陷。


 

课程下载地址:http://u.115.com/file/e60px8bk

文档下载地址:http://download.csdn.net/source/3437652

源码下载地址:http://u.115.com/file/aq2vc2re

原文地址:https://www.cnblogs.com/xiaoxiaoboke/p/2116254.html