iOS/Android 微信及瀏覽器中喚起本地APP
轉自:http://blog.csdn.net/linshijun33/article/details/71429669
需求概述
分享應用活動連結已經成為手機應用一個非常重要的推廣傳播形式。為了提高轉化率,就需要讓使用者不管是在微信或者是瀏覽器中,都能在點選連結後, 喚起本地的 app 後 , 跳轉到指定頁面 。
雖然這個功能從使用者體驗方面來說是自然而然的,但是由於 iOS/Android 平臺差異性,在實現過程中還是有些問題。
-
未安裝 app 時,如何做好引導頁,引導使用者下載後開啟 app 後,是否可以開啟之前喚醒前指定的頁面或內容
-
如何繞過微信的
scheme
遮蔽,在微信中喚醒 app 中,並開啟指定頁面 -
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
universal link 和 App Links
這裡的連結指的是深度連結 (deep learning)
,這是一種能夠方便地通過傳統的
http 連結來啟動 app 或網站。通過唯一的網址,就可以連結一個特定的檢視到你的 app 裡面不需要特別的 scheme。
iOS 的 universal link
使用要求:
使用步驟:
-
新增域名到
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 下載這個檔案。 -
構建
apple-app-site-association
檔案
該檔案必須存在且為了安全原因可使用 SSL 通過 GET 請求訪問到。你可以開啟一個文字編輯器然後寫一個這樣的簡單 JSON 格式:
根據 paths 鍵設定一個允許的路徑列表(你希望APP 作出反應的路徑), 設定 * 號則只是開啟 app 而已。
TEBEJCSf9DF 這一串是具有團隊標示的 bundle id。
檔案構建成功後,上傳這個檔案到你的域名根目錄。 -
在 app 裡處理通用連結
為了在 app 裡支援通用連結, 需要在 AppDelegate 裡實現[application(_:continueUserActivity:restorationHandler:)]
。 儘管這種方法可以用於許多不同的目的(比如 [Handoff]和 [搜尋 API]), 我們將只關注如何處理接收到的通用連結。
為了確保 app 可以翻譯 URL 成實際的內容, 需要做下面幾步:-
使用 [NSURLComponents]簡單解析 webpageURL 到 host(如domain。com), 路徑組成同理(如 [“/”]、”path”、”to”以及”thezoo”)。
-
確保能識別 host。
-
嘗試將 pathComponents 匹配到 APP 的已知內容裡。
-
驗證該內容實際上可以被呈現並呈現內容給使用者。
-
Android 的 App Links
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 來獲取。
預想可操作方案
-
連結頁面裡面有兩個按鈕:直接開啟和下載。直接開啟的話,判斷本地是否存在 app 後直接啟動 app,下載的話去到下載頁面。前端需要設計兩個頁面(分享的頁面,下載的頁面)。
-
使用
<a>
標籤的方式,來啟動客戶端。 -
區分渠道,判斷瀏覽器核心區分是 Android 還是 iOS,在 Android 6.0 以上,可使用 app links,在 iOS9.0 以上,可使用 universal link.但是這兩個都需要提供應用網站域名來繫結。其他系統版本通過自定義 scheme 來擷取。
-
補充下 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') 這樣寫完。你就會發現跳轉後底部不會出現那個該死的白條了 // 後面講一下原理 講一下。微信為什麼會出現這樣的問題 微信內建瀏覽器自己會監聽他會產生歷史記錄。一開始。我的想法就是隱藏這個東西。各種樣
根據瀏覽器判斷是否為Android、ios或微信環境
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、android、ios、微信瀏覽器
通過js userAgent來判斷判斷訪問此連結的作業系統<script> var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod")
實現base64格式的amr音訊檔案在IOS、android微信內建瀏覽器的播放
參考文件: 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 = ' <p style
微信小程式中的iOS相容性問題
記錄下在微信小程式中遇到的一些相容性問題,iOS相容性 1.iOS中input的placeholder屬性字型不居中 對placeholder設定line-height及font-size 對input設定高度 2.iOS中滾動卡頓 設定-webkit
一個API解決 區分當前使用應用的一切裝置平臺(Android、IOS、微信、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