標籤:android wap 網頁調起應用 自訂協議
Github博文地址,此處更新可能不是很及時。
好久沒寫部落格了,好大一個坑。正好,最近剛做完搜狗市場的高速下載功能,便拿來填了這個坑。
話說產品為了增加使用者量,提升使用者活躍度以及配合推廣,更坑爹的是看到其他市場也有這些功能,等等,要求做一個捆綁下載的功能。WTF。
當然吐槽歸吐槽,任務還是要完成的。
具體要求是: 使用者在手機瀏覽WAP網站的時候,1.進入應用詳情頁時開啟本應用(搜狗市場)裡面的詳情頁面 2.點擊WAP端高速下載時,如果本應用已安裝,則調用本應用進行下載,否則下載本應用的捆綁包,安裝完成之後,在本應用開啟時去下載之前使用者想下載的應用。 如何?這兩個功能呢?以下逐步分析:
1.功能需求
如之前所描述。
一般來說,完成之前的兩個功能,一般都是需要應用已安裝並且在後台運行(最簡單的理解就是應用開啟過應用,並且沒有被其他程式殺死),因此此處也預設這種情形才算應用已安裝;否則,一概認為是未安裝(以下沒有特別說明,均為這種情況)。
2.競品分析
當然,既然競品有了這些功能,那就先拿來主義,研究下他們是怎麼做的吧。通過Chrome抓包分析,最後分析如下。
百度手機小幫手 http://127.0.0.1:6259/
搜狗手機小幫手 http://127.0.0.1:12388/
豌豆莢 自訂協議wandoujia://detail/app/cn.buding.martin
百度手機小幫手以及搜狗手機小幫手的方案基本是一致的,採用的是訪問一個手機本地服務地址127.0.0.1(迴環地址),連接埠地址有所不同,豌豆莢採用的是自訂協議,後續讓瀏覽器自動幫它分發給註冊了wandoujia協議的Activity。
開啟應用詳情 這個在開啟瀏覽器相應詳情頁面時,百度手機小幫手以及搜狗手機小幫手同時訪問本地迴環地址,而豌豆莢則調用自訂協議由系統調用相關的應用(一般就是豌豆莢)。
高速下載原理 豌豆莢沒有實現在應用已安裝情形下調用用戶端進行下載,在點擊下載時,詢問用是下載捆綁包還是直接下載想要下載的應用(描述文案見文末附圖,文案有誘導性)。選擇下載捆綁包,則下載一個特定檔案名稱的豌豆莢安裝包。在安裝完成之後,去掃描特定的目錄(一般是download以及常見瀏覽器的下載目錄),如果存在符合規則的檔案,則提取相關的資源ID,後續再下載捆綁的APP。
- 在應用沒有安裝的情形下。而百度手機與搜狗手機小幫手點擊高速下載(名字也有誘導),則直接下載一個APP,所有APP內容一樣,但是APP名字有所不同,均類似於app_捆綁id_xx.apk,比如搜狗手機小幫手捆綁的為MobileTools_8271386494777466339_71.apk,捆綁其他包的捆綁id有所不同。其他流程同豌豆莢。如果存在多個合格apk,搜狗手機小幫手則取最新的資訊進行下載,百度手機小幫手沒有研究。
- 如果手機APP已經安裝。豌豆莢沒有實現,而百度手機小幫手以及搜狗手機小幫手,則是瀏覽器網頁直接請求一個迴環地址(127.0.0.1:port/actionpath?parameter),port為連接埠地址,百度手機小幫手為6259,搜狗手機小幫手為12388。actionpath為需要進行的操作,不同的操作,值也不一致 parameter為相關操作的參數,在這裡把需要捆綁下載的APP資料傳過去。手機APP通過應用內的HTTP伺服器接收到相關資料後進行應用下載,同時返回相應的資料。
3.最後方案
調起詳情頁面,採用HTTP伺服器以及自訂協議兩種都可以,而且自訂協議不用一直在後台跑一個承載HTTP伺服器的Service,會比較省電。
後續的高速下載,豌豆莢是沒有了,既然之前說到自訂協議省電,能否考慮呢?再結合需求,看下,應用未安裝的情形下,直接下載捆綁包,兩種都沒有問題;應用已安裝的情形,調起用戶端進行下載。自訂協議可以做到嗎?如何知道應用是否安裝了呢?瀏覽器有相應的API嗎?顯然沒有,就算有,也只可能部分有,但是要支援所有的瀏覽器。唯一的辦法就是通過訪問HTTP伺服器,同時設定逾時時間,一定時候內沒有響應則認為應用未安裝,下載相應的捆綁包。而且,通過HTTP伺服器後續擴充也好,可以通過網頁伺服器與Web進行雙向互動,比如百度手機小幫手可以通過web獲得位置資訊。而自訂協議就顯然做不到這些。當然除了省電。
高速下載的調起解決了,那如果應用沒有安裝,在本應用安裝完成之後,如何知道之前使用者需要下載的是哪個應用呢?也就是捆綁應用的識別。 搜狗市場最開始的方案是在應用裡面(asset檔案夾下)打入一個檔案,存放有捆綁應用的id號。但是,針對少量應用可以(最開始為了測試捆綁效果時用過),目前來說,針對大量應用肯定不行,需要打大量的包,而且需要不少儲存空間。
參考競品的方案,確實很完美,但是,考慮目前大部分的手機安全或者清理軟體,都會在應用安裝成功後提示刪除安裝包,同時,瀏覽器的下載目錄可能會會變。那這裡能掃描整個SD卡,去尋找合格檔案嗎?肯定不行,太消耗時間了。
那在應用沒有安裝或者沒有在後台啟動並執行情形下,如何知道捆綁的應用id呢。以上兩個方案都不完美,如何解決。與後端彥飛探討過,在高速下載apk時,網頁記錄手機下載的捆綁app id以及packagename以及該裝置的唯一id(uuid),然後在開啟市場時,請求相應的介面並把uuid傳入,獲得資料,從而下載相應的應用。想法超贊,後來發現沒有實用價值,uuid暫時沒有一個合理的方案。關鍵在於兩端產生的都要唯一,mac,ip?如何產生?
後來吃飯與國暢探討後,考慮是不是可以調用本地代碼去執行相關任務?但仔細思考過後,發現這個一般是WebView與js進行互動。而目前的使用情境根本就無法做到。這個Webview必須要是自己應用內的才可以。
考慮多方面因素,最後決定,參考百度手機小幫手以及搜狗手機小幫手的方案,儘管有缺陷。 關於自訂協議模式,可參考此文章,android自訂協議和html載入時自動嘗試調用本地APP,以及Android 註冊監聽自訂協議,本文不做過多介紹。
最後的方案就是手機端後台通過Service運行一個HttpServer,監聽12307連接埠。
調起用戶端
1.高速下載
網頁端點擊高速下載時,訪問http://127.0.0.1:12307/appdown?downid=1&packagename=com.sogou.map
如果成功,返回json串形式為
{ "status":1, "message":"OK" }
status為0表示失敗,status為1表示成功。message為具體描述。
如果在一定時間內手機沒有響應,則預設應用沒有安裝,下載捆綁APK包。
如果手機端響應了,則網頁端不做任何處理,手機端獲得相應的downid以及packagename,先判斷應用是否已經安裝,如果安裝,則提示應用已安裝,如果未安裝,則提示使用者應用正在下載,然後加入下載列表。
2.開啟詳情頁面
http://127.0.0.1:12307/godetail?downid=1&packagename=com.sogou.map&backtohome=ture backtohome為true時,按下手機端的返回按鈕回到應用的首頁,為false時返回瀏覽器。(可參考豌豆莢,比如(http://www.wandoujia.com/apps/com.tencent.mm)[http://www.wandoujia.com/apps/com.tencent.mm]必須手機端訪問,User-Agent與PC訪問不同)
安裝包應用捆綁
如何識別捆綁的是哪個應用呢?
後續參考競品的實現方式,通過下載檔案名稱不同(檔案名稱有規則)的檔案,在使用者安裝應用並且開啟後去讀取下載檔案夾,判斷是否存在符合規則的apk。如果存在,提取相應的id,去進行相應的下載。只要伺服器提供介面讓瀏覽器在下載同一個檔案顯示為不同的檔案名稱即可。
比如搜狗手機小幫手的一個詳情地址為http://wap.sogou.com/app/apkdetail.jsp?ppid=34&cid=49&docid=8271386494777466339&e=1394,高速下載安裝包的地址是http://download.zhushou.sogou.com/zhushou/android/MobileTools.apk?dn=MobileTools_8271386494777466339_71.apk 下載下來的apk名稱為MobileTools_8271386494777466339_71.apk。捆綁的應用id為8271386494777466339,應用為。通過設定HTTP返回資料的headers的Content-Disposition欄位為attachment;filename="MobileTools_8271386494777466339_71.apk"就可以實現,一般來說,主流瀏覽器都支援該屬性。
因此,最終確定,APK的命名方式為SogouAppmall_binding_downid_9.apk,判斷應用為這種格式(可通過正則匹配)就會提取downid(downid必須為整數)。應用未安裝時,點擊高速下載,下載以上規則命名的apk到檔案夾。使用者安裝應用並開啟應用時,去掃描常用的下載檔案夾(常見的/download,/downloads,以及瀏覽器下載檔案夾等)裡面的apk,有符合規則的則提取某一個檔案中的id,提取完成之後,進行下載,同時把安裝包刪除(防止對之後進行幹擾)。考慮到同一個檔案夾可能有多個符合規則的安裝包,則按照時間順序取當前檔案夾符合規則的時間最近的兩個,其他的檔案夾的忽略,等下次啟動再處理(一般這種情況也比較少)。當然還有其他一些細節需要處理,此處不再詳談。
4.效能最佳化與展望
程式最佳化,是有追求的攻城師必須做的事情,因此,當然要最佳化嘍。
為了省電,指定了以下兩條策略。
1. 在網路變化時,如果沒有網路,則關閉服務,有網路,則開啟服務。解屏以及鎖屏時分別開啟以及關閉服務。
2. 有網,且螢幕開啟是觸發服務開啟的必要條件。可以大部分降低應用在鎖屏狀態下有網路變化而導致的耗電問題。
以上兩個策略可疊加使用,可能會有些問題,比如有些時候條件都符合,但是服務沒有開啟(網路十分頻繁的切換可能會導致)。
設定為以上條件是因為,後續的操作都是有網才能完成,其次,鎖屏狀態下,一般使用者是沒辦法觸發相關的流程的,除非程式自動觸發(即時通訊軟體接收資訊比如,或者自動下載,但是這太流氓了)才需要在鎖屏時在後台跑。
HTTP伺服器是用的Github上開源的Nanohttpd,http伺服器除了高速下載,也可以用在,比如傳輸資料到電腦,應用與網頁互動等等很多方面。
5.最終實現
可訪問http://m.app.sogou.com/ 查看最終效果。
大致的思路就是以上描述。希望對大家有所啟發,起個拋磚引玉的作用。
目前暫時未上線,估計等到11月5號。
6.相關工具以及附錄
(1)Chrome 開發人員工具+裝置模式(資料抓包)
(2)三個市場的下載的示範地址:百度手機小幫手,搜狗手機小幫手,豌豆莢
當時(2014-10-27的頁面如下)
(3)常見瀏覽器的APK下載路徑(#表示改行是注釋,每行一個目錄,目前不支援遍曆子目錄)
#this is the binding apk file path#this is a comment#some system default, Chrome, Opera, Opera mini, Sogou Broswer, ES File Explorer,Dolphin Browserdownload#meizu browser, some system defaultdownload/apkdownloads#uc browserUCDownloads#QQ BroswerQQBrowser/安裝包QQBrowser/下載qqbrowser/download#QQ Broswer HDQQBrowser#baidu broswerbaidu/flyflow/downloads#baidu appbaidu/searchbox/downloads#Maxthon BroswerMxBrowser/DownloadsTTDownload/installapkApplicationThunderDownload#liebao broswerkbrowser_fast/download/App#360 Broswer360Browser/download#360 Express Broswer360ExpressBrowser/download#2345 broswerDownload/2345瀏覽器下載/安裝包#hao123hao123/down/apkDolphinBrowserCN/downloadUCDLFilesQCDownloadLXDOWNLOAD/DOWNLOADapc/ApcBrowser/downloads#YueDong Broswer,Ignore,The apk file name is changed by the broswer,the same with 4G Explorer(do not support header's Content-Disposition attribute)#ydBrowser/download#4G-explorer/apks
哈哈哈哈,完美解決所有問題。之後還可以擴充。
本文來自RxRead‘s Blog,歡迎轉載,轉載請註明。
搜狗市場高速下載以及網頁端調起APP頁面研究與實現