android開發我的新浪微部落格戶端-OAuth認證過程中用WebView代替原來的系統內建瀏覽器

來源:互聯網
上載者:User

前面的文章的OAuth認證過程在擷取oauth_verifier碼是是通過調用android系統帶的瀏覽器進行使用者授權認證的, 具體見:android開發我的新浪微部落格戶端-使用者授權頁面功能篇(3.2)。

     當初的實現是這樣:

     1、首先在AndroidManifest.xml中配置給AuthorizeActivity添加如下配置<data android:scheme="myapp" android:host="AuthorizeActivity" /> ,這樣在瀏覽器中通過地址myapp://AuthorizeActivity啟動AuthorizeActivity這個Activity.

    2、在用android系統帶的瀏覽器顯示使用者授權頁面的時候,把"myapp://AuthorizeActivity"作為url參數CallBackUrl=myapp://AuthorizeActivity,這樣當使用者輸入完帳號和密碼會請求myapp://AuthorizeActivity?oauth_verifier=123456這個地址,這個時候就自然啟動了AuthorizeActivity這個Activity.

    3、當AuthorizeActivity被啟動的時候,在onNewIntent方法中通過Uri uri = intent.getData();擷取oauth_verifier值123456。

    這樣的實現有個弊端:

    就是當使用者認證是選擇用uc等第三方的瀏覽器進行使用者認證時,當使用者輸入帳號密碼後點擊授權按鈕後不會跳轉到AuthorizeActivity這個Activity,只有用android內建的瀏覽器才沒有問題。其實這個是個比較嚴重的問題了大多數的使用者都會用uc等第三方的瀏覽器了,這樣導致認證不能正常進行。

    最近在嘗試iphone下的oauth認證的時候發現一個很好的思路,那就是不要用系統帶的瀏覽器而且在自己的程式中嵌入一個WebView在這個WebView控制項中完成使用者授權認證而不再使用額外的瀏覽器。今天抽了空把在iphone下的實現思路搬到了android下,做了如下的嘗試。

    現在的實現是這樣:

    1、首先上面的那3點都可以不需要了,該刪除的刪除。

    2、建立一個名為WebViewActivity的ViewActivity,在這個ViewActivity就只有一個WebView控制項

    Layout檔案如下:

<?xml version="1.0" encoding="utf-8"?><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"     android:layout_height="wrap_content"    android:orientation="vertical">  <WebView   android:layout_height="wrap_content"            android:layout_width="wrap_content"  android:id="@+id/web">  </WebView>  </ScrollView>

3、修改OAuth過程在擷取(Request Token和Request Secret)後,啟動WebViewActivity,在這個WebViewActivity的WebView控制項顯示使用者認證的網頁,代碼實現如下:

//Url類似:http://api.t.sina.com.cn/oauth/authenticate?oauth_token=71c6df7fd0b4e1e5c491faa90b654fdf&from=xweiboString Url=getAuthenticationURL();Intent intent = new Intent(MainActivity.this, WebViewActivity.class);Bundle b=new Bundle();b.putString("url", url);intent.putExtras(b);startActivity(intent);

  4、在WebViewActivity中onCreate方法中擷取上面傳過來的url進行認證網頁顯示,代碼如下:

super.onCreate(savedInstanceState);        setContentView(R.layout.webview);        WebView wv =(WebView) findViewById(R.id.web);Intent i=this.getIntent();if(!i.equals(null)){            Bundle b=i.getExtras();            if(b!=null){                if(b.containsKey("url")){                     String url = b.getString("url");                                          //這行很重要一點要有,不然網頁的認證按鈕會無效                                          wv.getSettings().setJavaScriptEnabled(true);                     wv.getSettings().setSupportZoom(true);                     //wv.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);                     wv.getSettings().setBuiltInZoomControls(true);                                           wv.loadUrl(url);                }            }        }

 5、上面Url參數中我們並沒有提供CallBackUrl參數,這個時候當使用者輸入帳號和密碼點擊授權後會顯示pin碼(oauth_verifier值)頁面,而不在會跳轉,頁面如下:


 6、上一步中已經在WebView顯示出了授權碼,我們接下來要做的就是擷取這個授權碼176048,這個既然是顯示在WebView中的網頁,那麼我們擷取當前的這個WebView顯示的html代碼然後從中提取出授權碼不就可以了。擷取html代碼是通過調用javascript實現的,不難就解釋了看具體代碼,在onCreate方法添加如下代碼:

wv.addJavascriptInterface(new JavaScriptInterface(), "Methods"); WebViewClient wvc=new WebViewClient()        {            @Override            public void onPageFinished(WebView view,String url)            {                view.loadUrl("javascript:window.Methods.getHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");                 super.onPageFinished(view, url);            }        };        wv.setWebViewClient(wvc);

添加類JavaScriptInterface

class JavaScriptInterface      {          public void getHTML(String html)          {              String pin= getPin(html);            //這裡就擷取到了我們想要的pin碼            //這個pin碼就是oauth_verifier值,用來進一步擷取Access Token和Access Secret用            Log.e("pin", pin);        }      }

 7、這樣我們就擷取到了當前WebView的html代碼,接下來就是提取html中的授權碼,html代碼如下:

<head><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width"><title>應用授權 - 新浪微博</title><link href="http://timg.sjs.sinajs.cn/t35/style/css/open/open_third.css" rel="stylesheet" type="text/css"></head><body><div class="opthBg">    <div class="opthTopBg"><div class="opthHead"><a href="http://weibo.com" class="newlogo"></a></div></div>    <div class="opthBox">         <div class="opthCen">             <br><br>            <font size="4"><b>擷取到授權碼:176048</b></font>            <br><br>            <div class="opthBottom">              <div class="lf"></div>              <div class="rt">              </div>            </div>         </div>    </div></div><script type="text/javascript">function canchange(){        document.forms['authZForm'].from.value='turnuser';        document.forms['authZForm'].action.value='';    document.forms['authZForm'].submit();}</script></body></head>

提取授權碼用正則實現的,java方法代碼如下:

public String getPin(String html)    {        String ret="";        String regEx="[0-9]{6}";        Pattern p=Pattern.compile(regEx);        Matcher m=p.matcher(html);        boolean result=m.find();        if(result)        {            ret= m.group(0);        }        return ret;    }

這樣就完成了所有的實現了,這做雖然有點麻煩,但是徹底解決了以前存在的問題。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.