突破Android微信微博瀏覽器限制直接拉起應

前言
衆所周知,微信微博等應用爲了防止用戶在使用過程中跳出程序自己,對瀏覽器裏面的自定義協議打開作了限制。這個需求很正常,是個產品經理都能想到。前端

但做爲微博微信這種體量的應用來講,我要多說幾句:「右上角使用瀏覽器打開」成了每一個前端開發者的標配,能夠說浪費了多少的人力和財力,亦能夠說造就了多少的就業機會。APP作得越大,越應該有社會責任感。這種簡單粗暴的方式讓千千萬萬的開發者感到心痛,無語。請把選擇權交還給用戶,既然用戶點開了瀏覽器,咱們也理解大家爲本身APP操碎了心,是否能夠作成彈框再讓用戶選擇:是否打開xx應用?android

現狀
H5頁面增長自定義協議拉起APP在移動端來說是個很是特點的交互,並且也能夠極大提升用戶體驗,基本是每一個應用的標配。經過git

<a href="orpheus://playlist/19850925" />

就能夠在點擊的時候觸發拉起應用(前提是系統已經安裝支持這個協議的應用,這個例子裏面叫orpheus。github

微信微博瀏覽器如何封禁自定義協議呢?web

public boolean shouldOverrideUrlLoading(WebView view, String url)

Android的WebView控件有個叫shouldOverrideUrlLoading的回調,任何連接的打開(包括http和各類自定義協議)都會先走這個回調,交給應用自己來判斷是否要接手處理,return true表示接手,WebView就再也不處理,不然WebView就繼續處理。
處理自定義協議其實不是WebView自帶的功能,而是須要開發者在這個回調裏面去實現。好比相似這樣:瀏覽器

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
}

那微信微博與其說攔截,倒不如說他們只判斷了本身白名單的協議而後放行。微信

方法
除了苦逼的前端開發者實現個右上角用瀏覽器打開功能,還有一些思路能夠參考。
1.假裝成白名單協議
咱們知道微信有白名單,好比合做的京東就能夠直接打開,因此咱們能夠把咱們的應用作成京東的協議名稱,這樣若是用戶手機上面沒有安裝京東,就能直接拉起你的應用。若是安裝了京東,則會跳出彈框讓用戶選用哪一個打開(這個是系統行爲)。這個方案有點猥瑣。
2.用右上角瀏覽器打開的時候能夠把本身應用置頂。咱們知道右上角用瀏覽器打開其實也是微信調用了上述那段代碼,只不過協議固定是http或者https。固然微信仍是作過修改的,第一個位置固定放QQ瀏覽器(即便沒有安裝)。除了第一個位置剩餘是按系統讀取的順序排列的。由於Intent實際上是有優先級的,那如何利用系統Intent優先級來讓本身的應用在這個彈框裏面排在第二位呢?異步

首先應用固然要實現支持http/https協議,否則你都不會出如今這個頁面裏面。而後給Intent配置域名信息,以下:
這樣在本身域名匹配上面排列就會靠前。甚至你能夠在這個協議實現上面,直接將http/https的url轉換成native參數,直接打開native頁面,省去中間webview跳轉。
若是url轉成native參數有點麻煩,你能夠在分享連接的時候帶上Intent.toUri做爲參數,這樣後續收到url以後直接Intent.parseUri獲得Intent,跳轉到指定頁面就簡單了。固然這種作法有限制,好比參數不能缺失,也不能支持其餘平臺分享過來的連接。若是應用的不一樣平臺能統一跳轉協議也是很不錯的。ide

突破
還能再作點什麼嗎?答案是確定的。這個突破不是絕對的,而必需要求程序在後臺有個活着的進程。若是你感興趣請繼續往下看。url

首先咱們知道系統的不少彈框都是用Activity實現的,他能夠彈出在任何應用的任意一個界面上面,說到底這個彈框也是屬於系統的某個應用,好比手機管家等等。那爲何一個APP在後臺能啓動的一個Activity能夠在任意另一個APP上面呢?
祕密就在於Intent.FLAG_ACTIVITY_NEW_TASK這個flag,咱們知道若是context.startActivity裏面的context不是Activity,是必需要加這個flag才能啓動成功。
第一個問題解決了,在android上面是有可能讓咱們的一個頁面呈如今微信之上。那如何觸發調用呢?聰明的你可能想到了,對,就是在H5頁面上面給本身應用發請求。
在本身應用裏面實現一個很是簡單的HttpServer,接聽來自本機的請求,一旦收到請求則直接使用Intent.FLAG_ACTIVITY_NEW_TASK拉起Activity。

惋惜是當你去嘗試在H5頁面裏面給127.0.0.1或者localhost發請求的時候發現根本收不到,由於狡猾的微信微博瀏覽器限制了這兩個本機地址,限制方式也很簡單,仍是剛纔的shouldOverrideUrlLoading判斷下url的host是否是這2個就能夠了。因而聰明的你確定又想到了繞過的方式。沒錯隨便弄個域名解析到127.0.0.1上面。

因而整個鏈路快要完成了,剩下就是一些額外的工做,好比客戶端和H5頁面約定一串端口,按照約定順序依次遍歷直到請求獲得響應。由於端口有可能被佔用。而後再約定一個加解密方式以防止被惡意攻擊。

這種方式有沒有可能被微信微博封禁呢?由於原理都是系統實現,惟一的可能點就是對域名進行解析發現仍是127.0.0.1的話繼續攔截。但這個作法有點代價,首先shouldOverrideUrlLoading不能阻塞調用,這樣就影響正常使用了。若是作成異步的就須要新增一個dns查詢服務,這個徹底看xx產品經理的意思。可能原來不會考慮,這篇文章發出去了用的人多了估計會考慮了。。。請給開發者留一條活路。

寫到這裏我猜你確定在想,程序活着這個條件是個硬傷,雖然多邁出了一步但仍是受限很多。因而又引出了一個古老的話題:如何程序保活。這不是本篇文章的範疇,我也不推薦你去研究和花費心思,這也不是一個正確的方向。
最後給一個提示:你的公司有沒有兄弟產品,亦或是有沒有使用一個公共的SDK呢?

更多細節請參考我給的例子,點擊這裏連接能夠參看。有任何問題歡迎留言討論,喜歡就點贊,請支持原創。

更多文章請關注微信公衆號:安卓之美

相關文章
相關標籤/搜索