瀏覽器判斷是否安裝了ios/android客戶端程序

<html>
<head>
<metaname="viewport"content="width=device-width"/>
</head>
<body>
<h2><aid="applink1"href="mtcmtc://profile/116201417">Open scheme(mtcmtc) defined in iPhone with parameters </a></h2>
<h2><aid="applink2"href="unknown://nowhere">open unknown with fallback to appstore</a></h2>
<p><i>Only works on iPhone!</i></p>
<scripttype="text/javascript">
            // To avoid the "protocol not supported" alert, fail must open another app. 
            var appstore = "itms://itunes.apple.com/us/app/facebook/id284882215?mt=8&uo=6"; 
            function applink(fail){ 
                return function(){ 
                    var clickedAt = +new Date; 
                  // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
                    setTimeout(function(){ 
                              // To avoid failing on return to MobileSafari, ensure freshness! 
                              if (+new Date - clickedAt <2000)
                              { 
                                  window.location = fail; 
                              } 
                              }, 500);     
                }; 
            } 
            document.getElementById("applink1").onclick = applink(appstore); 
            document.getElementById("applink2").onclick = applink(appstore); 
</script>
</body>
</html>


其原理就是爲HTML頁面中的超鏈接點擊事件增加一個setTimeout方法.

如果在iPhone上面500ms內,本機有應用程序能解析這個協議並打開程序,則這個回調方法失效;如果本機沒有應用程序能解析該協議或者500ms內沒有打開個程序,則執行setTimeout裏面的function,就是跳轉到apple的itunes。


我用同樣的原理來處理android的javascript跳轉,發現如果本機沒有程序註冊intent-filter for 這個協議,那麼android內置的browser就會處理這個協議並且立即給出反應(404,你懂的),不會像iPhone一樣去執行setTimeout裏面的function,即便你把500ms改成0ms也不管用。

我就開始了我的Google search之旅,最終在stackoverflow一個不起眼的地方找到solution。

不解釋,先給出源代碼

android裏面androidManifest.xml文件對activity的配置,如何配置就不表述了,表達能力有限,請參考developer.android.com

<activityandroid:name=".ui.UploadActivity"android:screenOrientation="portrait">
<intent-filter>
<dataandroid:scheme="http"android:host="192.168.167.33"android:port="8088"android:path="/mi-tracker-web/download.html"/>
<actionandroid:name="android.intent.action.VIEW"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<categoryandroid:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>

HTML頁面中指向該應用程序的hyperlink

<aid="applink1"href="http://192.168.167.33:8088/mi-tracker-web/download.html">
            Open Application</a>


不難發現,在androidManifest.xml中配置的filter中data的屬性表述,在下面的HTML.href中全部看到了。請注意,這兩個路徑要全部一致,不能有差別,否則android系統就不會攔截這個hyperlink。

好了,爲什麼我說這個solution能解決我們當初提出來的需求呢,答案在這裏:

如果說本機安裝了這個應用程序

在android browser中點擊HTML中的applink1,browser會重定向到指定的鏈接,但是由於我們的應用程序在android OS中配置了一個intent-filter,也是針對這個制定的鏈接。就是說現在android系統有兩個程序能處理這個鏈接:一個是系統的browser,一個是配置了intent-filter的activity。現在點擊這個鏈接,系統就會彈出一個選擇:是用browser還是你指定的activity打開。如果你選擇你的activity,系統就會打開你的應用程序,如果你繼續選擇用browser,就沒有然後了。


如果說本機木有安裝這個應用程序

那麼這個HTML裏面的這個超鏈接就起很重要的左右了,這個download.html裏面可以forward到android的應用商店

download.jsp源代碼如下。具體爲什麼請求的是download.html這個地址卻訪問到了download.jsp,就不解釋了,struts2的東西。


<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<scripttype="text/javascript">
<spanstyle="white-space:pre"></span>window.location="market://search?q=com.singtel.travelbuddy.android";</script>
</body>
</html>
唉,文筆不行,估計我寫出來自己都不怎麼看得懂。就再把跳轉的關鍵點說一下:


在androidManifest.xml中定義intent-filter的時候定義的scheme,host,port,path拼湊起來是一個有用的HTTP路徑,這樣就算本機沒有activity定義了intent-filter來捕獲這個鏈接,那這個鏈接也會重定向到打開android market place的頁面,繼而打開應用商店。因爲每個android手機都會捕獲到market這個協議(如果android手機裏面沒有market商店,不怪我哈),系統就會自動打開market place應用商店並根據參數進入搜索頁面並顯示結果。


html文件:

<html><head></head>
<body>
testkl 
<script>
function currentDevice () { 
    var ua = navig ator.userAgent; 
    var returnedHash = { 
        "iOS" : (ua.match(/MobileSafari/i) != null), 
        "iPod": (ua.match(/iPod/i) != null), 
        "iPad": (ua.match(/iPad/i) != null), 
        "iPhone": (ua.match(/iPhone/i) != null) 
    }; 
    if (returnedHash['iPad'] || returnedHash['iPod']) { 
        returnedHash['iPhone'] = false; 
    } 
    returnedHash['canMakePhoneCalls'] = returnedHash['iPhone']; 
    returnedHash['canHandleMapLinks'] = returnedHash['iOS']; 
    return returnedHash; 
} 
var is_device = currentDevice(); 
if (is_device.iPhone) { 
document.location = 'xywyask://test'; 
    setTimeout(function() { 
        //if (confirm('是否要安裝「問醫生」iPhone App?')) { 
document.location = 'itms:://itunes.apple.com/cn/app/wen-yi-sheng/id551521341?mt=8'; 
        //} 
    }, 100); 
}else{ 
alert("as"); 
} 
</script>




其他參考資料:

http://gibuloto.com/blog/ios-open-app-from-url/


http://www.baidufe.com/item/cc592a4b3382eed8ec6e.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章