1. 程式人生 > >iOS/Android 微信及瀏覽器中喚起本地APP

iOS/Android 微信及瀏覽器中喚起本地APP

轉自:http://blog.csdn.net/linshijun33/article/details/71429669

需求概述

分享應用活動連結已經成為手機應用一個非常重要的推廣傳播形式。為了提高轉化率,就需要讓使用者不管是在微信或者是瀏覽器中,都能在點選連結後, 喚起本地的 app 後 , 跳轉到指定頁面 。

雖然這個功能從使用者體驗方面來說是自然而然的,但是由於 iOS/Android 平臺差異性,在實現過程中還是有些問題。

  1. 未安裝 app 時,如何做好引導頁,引導使用者下載後開啟 app 後,是否可以開啟之前喚醒前指定的頁面或內容

  2. 如何繞過微信的  scheme  遮蔽,在微信中喚醒 app 中,並開啟指定頁面

  3. iOS 專用的  universal link ,Android 專用的  App Links  的整合要求,有哪些侷限性。

現實情況

在實施過程中,還是有兩個地方是沒辦法忽略的:

scheme 被微信遮蔽了

除非一些和微信有合作的 app 可以進入到白名單,其他的應用在微信內都沒辦法通過自定義 scheme 協議直接喚起 app,前端頁面需要對喚起場景進行判斷。

瀏覽器無法明確地判斷本地是否已經安裝 app

目前的取巧方案就是通過  setTimeOut  設定超時時間,在超時時間內喚起 app,然後獲得成功失敗回撥,如果獲得的是失敗的回撥,則說明本地沒有安裝 app,需要跳轉到商店下載頁面。

實現方案

踩坑方案

鑑於在開啟 url scheme 的方法中,iOS9 和 iOS8/iOS7 區別很大,Android 不同廠商的是適配也不同,這裡介紹的踩坑方案都是前人實踐總結出來的。

兩種開啟方式:

一、 直接跳轉:點選連結或者修改  window.location 。 
點選連結:

<a href="schemeUrl">喚醒你的APP</a>
  • 1
  • 1

修改 window.location:

window.location.href = schemeUrl;
  • 1
  • 1

這種情況,如果APP喚醒失敗,或者APP未安裝的話,很多時候都會跳到錯誤頁,這很影響使用者體驗,而我們的要求可能是跳轉到其他頁面或者下載APP。

二、 iframe  跳轉:在 body 上新增 iframe,設定 src 屬性為跳轉的 URL scheme

<a href="APP下載地址">下載或開啟APP</a>
<script>
  $('a').click(function() {
      var ifr = document.createElement('iframe');
          ifr.src = '自定義 URL scheme';
          ifr.style.display = 'none';

      document.body.appendChild(ifr);
      setTimeout(function(){
          document.body.removeChild(ifr);
      }, 3000);
  });
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

這一種方法不會引起頁面內容可見的變化,不會導致瀏覽器歷史記錄的變化, 
實現過程是:點選 a 標籤時,開啟 自定義 scheme。若成功,就喚起 app,若失敗,就到 href 屬性,去到下載地址。

相應的,在 Android 客戶端這邊,需要在 manifest 檔案裡面配置 intent-filter,如下:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="自定義 URL scheme" />
</intent-filter>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意這裡的  intent-filter  的這幾個配置不能再和 action.MAIN 放在一起。如果是在同一個 activity 中配置,那麼可以配置兩個 intent-filter ,比如

<!-- 第一個filter -->
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<!-- 第二個filter -->
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="mls" />
</intent-filter>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

理論上,在 Android 上這兩種方式應該都是可以順利實現的。但是 Android 的 chrome 核心從 chrome 25 以後就棄用了 iframe,不再支援通過 js 觸發(非人為點選)或者通過設定  iframe src  地址來觸發 scheme 跳轉。所以,後一種方法在適配上存在比較多的問題。故一般選擇前面一種做法,即 href 的點選或者 window.location 跳轉。

使用第一種方案,setTimeOut 派上用場。

$('a').click(function() {
    location.href = '自定義 URL scheme';
    t = Date.now();

    setTimeout(function(){
        if (Date.now() - t < 1200) {
            location.href = 'Android 下載地址';
        }
    }, 1000);

    return false;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

理想過程是這樣:瀏覽器嘗試開啟 URL scheme,在 1 秒計時後,檢查當前時間,如果實際時間已過 1200 毫秒,說明喚起 app 成功(喚起 app 會讓瀏覽器的定時器變慢);如果沒超過 1200 毫秒,很可能是沒有安裝應用,就跳到下載地址。

但是這麼做也是有問題的,因為 Android 系統是多工系統,setTimeOut基本就沒那麼精準,不能起到理想效果。換一種方式, setInterval ,如果設定比較小的執行間隔(<30ms),在瀏覽器或者 webview 中,應用切換到後臺,setInterval 會被很明顯的延遲執行,比如設定一個執行間隔 20ms,總計執行 100 次的定時器,如果頁面一直處於前臺,則 100 次跑完,總耗時與 100x20=2000ms 不會有太大差異,但頁面在後臺執行時,此時間會明顯超過 2000ms。可以利用這一點來實現是否成功開啟 app 檢測及回撥。

function openApp(openUrl, appUrl, action, callback) {
    // 檢查 app 是否開啟
    function checkOpen(cb){
        var _clickTime = +(new Date());
        function check(elsTime) {
            if ( elsTime > 3000 || document.hidden || document.webkitHidden) {
                cb(1);
            } else {
                cb(0);
            }
        }
        // 啟動間隔 20ms 執行的定時器,並檢測累計消耗時間是否超過 3000ms,超過則結束
        var _count = 0, intHandle;
        intHandle = setInterval(function(){
            _count++;        
            var elsTime = +(new Date()) - _clickTime;
            if (_count>=100 || elsTime > 3000 ) {
                clearInterval(intHandle);
                check(elsTime);
            }
        }, 20);
    }

    // 在 iframe 中開啟 app
    var ifr = document.createElement('iframe');
    ifr.src = openUrl;
    ifr.style.display = 'none';
    if (callback) {
        checkOpen(function(opened){
            callback && callback(opened);
        });
    }

    document.body.appendChild(ifr);      
    setTimeout(function() {
        document.body.removeChild(ifr);
    }, 2000);  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

iOS9 上 iframe 也不可用

在 iOS 9 上,iframe 方案變得不可用。在開啟自定義 URL scheme 時,會彈出對話方塊,詢問是否用 xx 應用來開啟。往往使用者還沒來得及點選開啟,定時器又觸發了,導致跳到 App Store。 
可以在嘗試開啟URL scheme 後,再加一個頁面跳轉,這樣對話方塊會被覆蓋,再重新整理頁面,就能無需確認喚起 app:

$('a').click(function() {
    location.href = '自定義 URL scheme';
    location.href = '下載頁';
    location.reload();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

APP已安裝這是沒問題的,但如果APP未安裝,跳 App Store 的請求會失敗。 這時可以使用兩個定時器:

$('a').click(function() {
    location.href = '自定義 URL scheme';
    setTimeout(function() {
        location.href = '下載頁';
    }, 250);

    setTimeout(function() {
        location.reload();
    }, 1000);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

這裡的連結指的是深度連結 (deep learning) ,這是一種能夠方便地通過傳統的 http 連結來啟動 app 或網站。通過唯一的網址,就可以連結一個特定的檢視到你的 app 裡面不需要特別的 scheme。

使用要求: 
這裡寫圖片描述
使用步驟:

  1. 新增域名到  Capabilities  
    首先, 你必須在 Xcode 的 capabilities 裡 新增你的 APP 域名, 必須用 applinks: 前置它:還新增一些你可能擁有的子域和擴充套件(www.domain.com, news.domain.com 等等)。這將使你的 APP 從你的域名請求一個特殊的 JSON 檔案 apple-app-site-association。當你第一次啟動 APP,它會從 https://domain.com/apple-app-site-association 下載這個檔案。 
    這裡寫圖片描述

  2. 構建  apple-app-site-association  檔案 
    該檔案必須存在且為了安全原因可使用 SSL 通過 GET 請求訪問到。你可以開啟一個文字編輯器然後寫一個這樣的簡單 JSON 格式: 
    這裡寫圖片描述
    根據 paths 鍵設定一個允許的路徑列表(你希望APP 作出反應的路徑), 設定 * 號則只是開啟 app 而已。 
    TEBEJCSf9DF 這一串是具有團隊標示的 bundle id。 
    檔案構建成功後,上傳這個檔案到你的域名根目錄。

  3. 在 app 裡處理通用連結 
    為了在 app 裡支援通用連結, 需要在 AppDelegate 裡實現  [application(_:continueUserActivity:restorationHandler:)]  。 儘管這種方法可以用於許多不同的目的(比如 [Handoff]和 [搜尋 API]), 我們將只關注如何處理接收到的通用連結。 
    為了確保 app 可以翻譯 URL 成實際的內容, 需要做下面幾步:

    • 使用 [NSURLComponents]簡單解析 webpageURL 到 host(如domain。com), 路徑組成同理(如 [“/”]、”path”、”to”以及”thezoo”)。

    • 確保能識別 host。

    • 嘗試將 pathComponents 匹配到 APP 的已知內容裡。

    • 驗證該內容實際上可以被呈現並呈現內容給使用者。

Android 手機上,開啟連結通常會跳出選擇框選擇用什麼瀏覽器開啟,而使用 app links,當點選了連結,安卓系統會檢查是否有一個 app 可以處理 url(比如 twitter.com),然後跟核對哪個app(s)可以處理該域名的連結,直接在應用內處理,這樣我們就能避免彈框影響使用者。

和 iOS 一樣,Android 的深度連結也需要相關的域名來配合,有以下的條件: 
這裡寫圖片描述

想要讓你的 app 處理連結,需要在 manifest 檔案中使用 intent filter 宣告 app 需要處理的 uri 模式。下面的例子,聲明瞭一個  intent filter  能夠處理 http://www.android.com 和 https://www.android.com

<activity …>
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:host="www.android.com" />
    </intent-filter>
</activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

配置  autoVerify 來觸發系統自動校驗。

如何驗證成功?這就需要網站所有者必須宣告和app的聯絡。網站所有者通過持有一個名為  assetlinks.json  的 Digital Asset Links JSON 檔案來宣告與一個 app 的聯絡,它在 domain 的well-known 位置:https://domain[:optional_port]/.well-known/assetlinks.json。 
注意:系統通過加密的 HTTPS 協議來驗證 json 檔案,所以不管 intent filter 中是否聲明瞭 https,請確保 json 檔案能夠通過 HTTPS 連線來獲取。 
Digital Asset Links JSON 檔案聲明瞭與此網站關聯的 app,下面的示例 assetlinks.json 檔案允許包名為 com.example 的app開啟連結:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

sha256 可以通過 keytool 來獲取。

預想可操作方案

  1. 連結頁面裡面有兩個按鈕:直接開啟和下載。直接開啟的話,判斷本地是否存在 app 後直接啟動 app,下載的話去到下載頁面。前端需要設計兩個頁面(分享的頁面,下載的頁面)。

  2. 使用<a> 標籤的方式,來啟動客戶端。

  3. 區分渠道,判斷瀏覽器核心區分是 Android 還是 iOS,在 Android 6.0 以上,可使用 app links,在 iOS9.0 以上,可使用 universal link.但是這兩個都需要提供應用網站域名來繫結。其他系統版本通過自定義 scheme 來擷取。

  4. 補充下 Android 的呼叫流程: 
    這裡寫圖片描述
    由於好多初始化工作都在 SplashActivity 裡面做了,所以開啟的流程也是從上到下一步一步開頁面,資料也需要傳遞過去。遇到需要登入的時候,先跳登入頁,再跳詳情頁,把登入頁從棧中清掉,返回時,就能從詳情頁 DetailActivity 回到 MainActivity 了。


相關推薦

iOS/Android 瀏覽器喚起本地APP

轉自:http://blog.csdn.net/linshijun33/article/details/71429669 需求概述 分享應用活動連結已經成為手機應用一個非常重要的推廣傳播形式。為了提高轉化率,就需要讓使用者不管是在微信或者是瀏覽器中,都能在點選連結後

基於應用寶實現h5頁面開啟本地app,如果沒有跳轉下載頁面的解決方案

首先這個方法是基於微信中開啟的h5頁面的,如果是外接瀏覽器的話則無論是否有該app都會執行下載 <a href="http://d.xiaojukeji.com/c/73852">

小程式呼叫本地介面

1.點選詳情,並勾選專案設定中最後一行。   2.用小程式請求本地的後臺服務介面 wx.request({ url: 'http://localhost:8090/DemoProject/myTest.do', data:{},

iOS支付(二)——本地生成訂單整合詳情

對於微信支付,可能還有很多人只知道從伺服器拿到相關引數然後去完成支付,感覺很簡單,不過也確實比較簡單,就那麼幾步,為什麼如此簡單呢?因為後臺幫我們完成了大概百分之八十的工作量,到咱們整合的時候肯定很

vue 專案 如何動態監聽瀏覽器以及iOS手機自帶的返回按鈕的事件

vue搭建的頁面中,左上角的返回按鈕,我自己定義了返回的了路徑,可是當執行時,就會發現,蘋果手機的下方會有自帶的返回按鈕(安卓手機沒有),那麼這個按鈕的返回事件該如何設定呢? 一般情況下,微信自帶的返回按鈕都是返回上一個路徑,可是當我的頁面時使用者掃碼進入的,沒有上一條路徑

瀏覽器喚起手機默認瀏覽器的實現方式

csdn 體驗 lan 基於 默認 ios 就會 src .net 需求概述 分享應用活動鏈接已經成為手機應用一個非常重要的推廣傳播形式。為了提高轉化率,就需要讓用戶不管是在微信或者是瀏覽器中,都能在點擊鏈接後,?喚起本地的 app 後?,?跳轉到指定頁面?。 雖然這個功能

vue 解決IOS內建瀏覽器底部前進後退的bar

對於急性子先講一下解決方案 this.$router.replace('/path') 這樣寫完。你就會發現跳轉後底部不會出現那個該死的白條了 // 後面講一下原理 講一下。微信為什麼會出現這樣的問題 微信內建瀏覽器自己會監聽他會產生歷史記錄。一開始。我的想法就是隱藏這個東西。各種樣

根據瀏覽器判斷是否為Androidios環境

agen navig 相關信息 agent san ipa andro span hone 寫h5頁面時經常有業務邏輯需要判斷頁面所處的環境,這時我們可以通過navigator對象來獲取瀏覽器相關信息加以判斷,方法如下:    let ua = navigator.use

通過UserAgent判斷智慧手機(裝置,Android,IOS)、瀏覽器

定義和用法 userAgent 屬性是一個只讀的字串,聲明瞭瀏覽器用於 HTTP 請求的使用者代理頭的值。 一般來講,它是在 navigator.appCodeName 的值之後加上斜線和 navigator.appVersion 的值構成的。 例如:Mozilla/4

JS 判斷PC、androidios瀏覽器

通過js userAgent來判斷判斷訪問此連結的作業系統<script> var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod")

實現base64格式的amr音訊檔案在IOSandroid內建瀏覽器的播放

參考文件: 1.https://github.com/yxl/opencore-amr-js   (將amr檔案轉為wav格式的編解碼專案) 因為專案需要,要將amr的base46格式的音訊檔案在IOS,android微信內建瀏覽器播放。專案中使用的第三方IM為融雲,經過

ios瀏覽器如何喚醒app?app已上架應用寶

roi eply android 應用寶 地址 微信瀏覽器 ply andro 下載地址 android下可以通過在應用寶微下載地址後面加參數&android_schema=‘應用schema‘來實現,ios下如何實現?

JS監聽、支付寶等移動app瀏覽器的返回、後退、上一頁按鈕的事件方法

on() 移動app 自己的 win 功能 監聽 ner tor event $(function(){ pushHistory(); window.addEventListener("popstate", function(e) { alert("我監聽到

去除富文字的html標籤vue、react、小程式的過濾器

在獲取富文字後,又只要顯示部分內容,需要去除富文字標籤,然後再擷取其中一部分內容;然後就是過濾器,在微信小程式中使用還是挺多次的,在vue及react中也遇到過 1.富文字去除html標籤 去除html標籤及 空格 let richText = ' &lt;p style

小程式iOS相容性問題

記錄下在微信小程式中遇到的一些相容性問題,iOS相容性 1.iOS中input的placeholder屬性字型不居中 對placeholder設定line-height及font-size 對input設定高度 2.iOS中滾動卡頓 設定-webkit

一個API解決 區分當前使用應用的一切裝置平臺(AndroidIOS、QQ等等一切有提供支援的)

Window Navigator 示例: <div id="example"></div> <script> var txt = ''; txt = "<p>Browser CodeName: " + navigator.appCodeName

很多人都不知道的監聽、支付寶等移動app瀏覽器的返回、後退、上一頁按鈕的事件方法

在實際的應用中,我們常常需要實現在移動app和瀏覽器中點選返回、後退、上一頁等按鈕實現自己的關閉頁面、調整到指定頁面或執行一些其它操作的 需求,那在程式碼中怎樣監聽當點選微信、支付寶、百度糯米、百度錢包等app的返回按鈕或者瀏覽器的上一頁或後退按鈕的事件呢。 我相信很多朋

ios瀏覽器輸入框失去焦點後頁面不能回彈

問題:註冊頁面,輸入完手機號和註冊密碼,點選獲取驗證碼,圖片驗證碼彈窗彈出,一切進行的都很完美。然而在ios微信瀏覽器裡面,無論點選哪裡,彈出層毫無響應。 開始排查問題: 首先排除不是z-index導致元素點不到,進而無法觸發點選事件。 因為使用vue框架,所

小程式獲取時間戳IOS不相容

一、時間轉換問題: 就是new  Date("2017-06-16") 在IOS會出現NAN的情況所以對於時間轉換需要另行封裝,解決方案如下 1.替換”-“為”/“ var thisData = r_that.data.thisDate.replace(/-/g,

android高仿圖片瀏覽器

專案中用到圖片瀏覽 拆分出來 以後方便使用 高仿微信圖片瀏覽器 module使用 rxjava + okhttp3 + fresco 所以專案中引用以後 會增大安裝包體積2m左右 如果你的專案中沒有使用rxjava 和 okhttp3 和fresco