H5喚起APP進行分享的嘗試

H5喚起APP進行分享

最近很久沒有寫blog和note,倒是過家家的開發日誌簡單草草寫了一點。這次記錄下這個學習過程

由來

我們的 "通達有你",web h5頁面的分享功能體驗太差了,我一直想改變提高體驗度。

通常點分享然後跳轉到另一個頁面,比如QQ、空間、微博,還有微信。微信通常要掃二維碼分享,(我們只有一個手機啊,還要再屏幕上掃二維碼,通常要是我是嘗試分享者,微信這麼麻煩的分享我肯定是不會繼續分享了)

所以剛有空我就想試試更好的方法

疑問?

然後我平時留意幾大互聯網的巨頭的h5頁面,他也是可以進行APP喚起的,這到底是怎麼做到的?

不過這種情況分爲兩種:

  1. 喚起自己產品的APP

  2. 喚起第三方APP

    image

image

而我的目的是第二種,我們是要喚起第三方APP進行分享

分析實現方式

經過我 面向搜索引擎 的一頓操作,瞭解到一些資料和方式,其中要實現在h5喚起APP的主要採用

  1. URL Scheme | Intent | Universal Link(也稱:深度鏈接)
  2. 通過瀏覽器的內置native分享接口

URLScheme

URL Scheme 是什麼

我們來看一下 URL 的組成:

[scheme:][//authority][path][?query][#fragment]

我們拿 https://www.baidu.com 來舉例,scheme 自然就是 https 了。

就像給服務器資源分配一個 URL,以便我們去訪問它一樣,我們同樣也可以給手機APP分配一個特殊格式的 URL,用來訪問這個APP或者這個APP中的某個功能(來實現通信)。APP得有一個標識,好讓我們可以定位到它,它就是 URL 的 Scheme 部分。

常用APP的 URL Scheme

APP 微信 支付寶 淘寶 微博 QQ 知乎 短信
URL Scheme weixin:// alipay:// taobao:// sinaweibo:// mqq:// zhihu:// sms://

URL Scheme 語法

上面表格中都是最簡單的用於打開 APP 的 URL Scheme,下面纔是我們常用的 URL Scheme 格式:

     行爲(應用的某個功能)    
            |
scheme://[path][?query]
   |               |
應用標識       功能需要的參數

蒐集到的常用Scheme

應用名稱 URL Scheme
微博 weibo://
QQ mqq://
QQ羣組 mqqapi://card/show_pslcard?src_type=internal&version=1&card_type=group&uin={QQ羣號}
QQ聯繫人 mqqapi://card/show_pslcard?src_type=internal&version=1&uin={QQ號碼}
支付寶 alipay://
微信 weixin://
微信 wechat://
微信-掃一掃 weixin://dl/scan
微信-反饋 weixin://dl/feedback
微信-朋友圈 weixin://dl/moments
微信-設置 weixin://dl/settings
微信-消息通知設置 weixin://dl/notifications
微信-聊天設置 weixin://dl/chat
微信-通用設置 weixin://dl/general
微信-公衆號 weixin://dl/officialaccounts
微信-遊戲 weixin://dl/games
微信-幫助 weixin://dl/help
微信-反饋 weixin://dl/feedback
微信-個人信息 weixin://dl/profile
微信-功能插件 weixin://dl/features
蝦米音樂 xiami://
chrome googlechrome://
微博國際版 weibointernational://
摩拜單車 mobike://
ofo ofoapp://
有道雲筆記 youdaonote://
印象筆記 evernote://
今日頭條 snssdk141://
網易新聞 newsapp://
網易雲音樂 orpheuswidget://
QQ音樂 qqmusic://
QQ音樂最近播放 qqmusic://today?mid=31&k1=2&k4=0
美團外賣 meituanwaimai://
美團 imeituan://
Gmail googlegmail://
網易郵箱 neteasemail://
QQ郵箱 qqmail://
騰訊視頻 tenvideo://
愛奇藝 iqiyi://
12306 cn.12306://
有道詞典 yddict://
釘釘 dingtalk://

我進入深坑

看到上面這些資料的我,思考了很久如何去找具體的path和query部分。如果能找到這兩塊的詳細參數,那麼我們就可以在APP間相互調用和傳參了,就和普通URL一樣了

但是,我尋找了好久,或許是我不懂這裏面的方式吧,或許是我也不太懂Android方面的知識,就是沒人在網上提及到具體的path和query,

後來想想,也是挺正常的,大多網站和企業只是想喚起自己的APP,那如何使用這些URL Scheme呢

大坑

先預告一下還有比較大的坑就是,scheme的觸發方式會被瀏覽器攔截,如果是QQ和微信自帶的內置瀏覽器,使用Scheme是無效的,除非是自家人或者在它的白名單內(比如幾大巨頭),這就導致瞭如果你在QQ和微信內點擊網頁內的分享,不好意思,啥用沒有。。。不過可以做個遮罩層用他們內置瀏覽器的右上角分享功能。

  • 微信、微博、手百、QQ瀏覽器等。

    這些應用能阻止喚端是因爲它們直接屏蔽掉了 URL Scheme 。接下來可能就有看官疑惑了,微信中是可以打開大衆點評的呀,微博裏面可以打開優酷呀,那是如何實現的呢?

    它們都各自維護着一個白名單,如果你的域名在白名單內,那這個域名下所有的頁面發起的 URL Scheme 就都會被允許。就像微信,如果你是騰訊的“家屬”,你就可以加入白名單了,微信的白名單一般只包含着“家屬”,除此外很難申請到白名單資質。但是微博之類的都是可以聯繫他們的渠道童鞋進行申請的,只是條件各不相同,比如微博的就是在你的 APP 中添加打開微博的入口,三個月內喚起超過 100w 次,就可以加入白名單了。

  • 騰訊應用寶直接打開 APP 的某個功能

    剛剛我們說到,如果你不是微信的家屬,那你是很難進入白名單的,所以在安卓中我們一般都是直接打開騰訊應用寶,ios 中 直接打開 App Store。點擊騰訊應用寶中的“打開”按鈕,可以直接喚起我們的 APP,但是無法打開 APP 中的某個功能(就是無法打開指定頁面)。

    騰訊應用寶對外開放了一個叫做 APP Link 的申請,只要你申請了 APP Link,就可以通過在打開應用寶的時候在應用寶地址後面添加上 &android_schema={your_scheme} ,來打開指定的頁面了。

感覺騰訊應用寶是個做文章的很地方,沒準之後會嘗試下

瀏覽器的內置分享原生分享

瀏覽器自帶有分享到微信和QQ的功能,但不是每個都提供接口來供網頁調用。即使有提供,瀏覽器暴露的api不一樣,各家有各家的規則和方式。

但好在網上找到了兩個前輩造的輪子NativeShareuc-qq-share-to-wechat ,也都是調用各個瀏覽器的原生分享功能,但前者裏面我還看到了部分Scheme的方式。

主要的瀏覽器有:

  • QQ瀏覽器
  • UC瀏覽器
  • 微信自帶瀏覽器
  • QQ自帶瀏覽器
  • QQ空間APP
  • 百度瀏覽器
  • 百度APP自帶瀏覽器
  • ios 搜狗瀏覽器
  • Safari瀏覽器
  • 其他

觸發方式

現在來說說觸發方式,大致上有三種:

iframe方案

<iframe src="sinaweibo://qrcode">

在未安裝 app 的情況下,不會去跳轉錯誤頁面。但是 iframe 在各個系統以及各個應用中的兼容問題還是挺多的,我自己並沒有使用這種。

var last = Date.now(),
    doc = window.document,
    ifr = doc.createElement('iframe');

//創建一個隱藏的iframe
ifr.src = nativeUrl;
ifr.style.cssText = 'display:none;border:0;width:0;height:0;';
doc.body.appendChild(ifr);

setTimeout(function() {
    doc.body.removeChild(ifr);
    //setTimeout回小於2000一般爲喚起失敗 
    if (Date.now() - last < 2000) {
        if (typeof onFail == 'function') {
            onFail();
        } else {
            //彈窗提示或下載處理等
        }
    } else {
        if (typeof onSuccess == 'function') {
            onSuccess();
        }
    }
}, 1000);

iframe方案的喚起原理是: 程序切換到後臺時,計時器會被推遲(計時器不準的又一種情況)。如果app被喚醒那麼網頁必然就進入了後臺,如果用戶從app切回來,那麼時間一般會超過2s;若app沒有被喚起,那麼網頁不會進入後臺,setTimeout基本準時觸發,那麼時間不會超過2s。

a標籤喚起

<a href="mqqapi://card/show_pslcard?src_type=internal&version=1&uin=123456">QQ臨時交流</a>

上面這個a標籤你可以自己嘗試一下,是可以直接喚起的,a標籤如果目標scheme錯誤,即應用不存在也不會報錯。

location.href跳轉

window.location.href = 'sinaweibo://qrcode';

我自己大多使用click的方式配合location來進行跳轉,自己沒有在各大平臺和各個瀏覽器版本上做太多實驗,在一個博文中看到

URL Scheme 在 ios 9+ 上諸如 safari、UC、QQ瀏覽器中, iframe 均無法成功喚起 APP,只能通過 window.location 才能成功喚端。

某篇博文中對三種喚起方式進行了測試

。X表示喚起失敗,√表示喚起成功
。紅色標記表示進入頁面直接喚起,綠色表示人工事件操作後喚起
。ios測試機:iphone 6p;android測試機:小米1s

iframe喚起app測試結果

圖片顯示

window.location.href喚起app測試結果

圖片顯示

a標籤喚起app測試結果

圖片顯示

iframe和window.location.href喚起對比

圖片顯示

iframe、window.location.href和a標籤喚起三者對比

圖片顯示

對比iframe喚起和location.href,我們可以發現:

  1. 對於ios來說,location.href跳轉更合適,因爲這種方式可以在Safari中成功喚起app。Safari作爲iphone默認瀏覽器其重要性就不用多說了,而對於微信和qq客戶端,ios中這兩種方式都沒有什麼卵用==
  2. 對於Android來說,在進入頁面直接喚起的情況下,iframe和location.href是一樣的,但是如果是事件驅動的喚起,iframe喚起的表現比location.href要更好一點。
  3. 通過測試可以發現,進入頁面直接喚起和事件驅動的喚起,對於很多瀏覽器,兩者的表現是不同的,簡單來說,直接喚起的失敗更多。

以上測試可能隨時間已經有出入和變化,僅供參考

選擇

看了這些資料後,開始動手對網站的分享功能再次二開,目前都是採用a標籤進行一個簡單的跳轉,去對應社交平臺的分享url的api接口提交各個參數。

image

嘗試

準備先引入大佬的NativeShare輪子,因爲我在他的在線demo嘗試了,我手機自帶瀏覽器、模擬器的自帶瀏覽器、模擬器的QQ瀏覽器,都可以很好的分享出來,於是首先引入他的方式。

思路

$(document).ready(function () {
    $(".social-share-icon ").on("click",function (e) {
        e.preventDefault();
        shareHref = $(this).attr("href");

        if ($(this).hasClass("icon-qq")){

            call('qqFriend',shareHref);

        }

    })
})

對目前的各個a標籤,在dom加載完成時添加一個click事件,阻止a標籤的觸發,然後把href地址記錄下來。然後再去觸發相應的NativeShare中的call方法。

但是我發現在原生的瀏覽器裏面竟然沒觸發。。那就做個降級處理吧。

function call(command) {
            try {
                nativeShare.call(command)
            } catch (err) {
                // 在這裏寫降級處理的內容
                alert(err.message)
            }
        }

在catch到拋出到異常後,自己在用原生的URL scheme 嘗試觸發,如果還是不能觸發,那就沒辦法咯~~

var url_scheme = '//share/to_fri?src_type=web&version=1&file_type=news&title=' + Base64.encode(shareData.title) + '&thirdAppDisplayName=5o6M5LiK55CG5bel5aSn&url=' + Base64.encode(shareData.link) + '&description=' + Base64.encode(shareData.desc);
            location.assign('mqqapi:' + url_scheme)
            setTimeout(function () {
                location.assign('timapi:' + url_scheme)
            }, 2000)

這個是我在網上找到的一個qq 分享的URL scheme,記得要base64處理下各個內容,還有個缺陷就是沒有icon了,圖片顯示不了了。

細節處理

剛剛都是說手機移動端訪問,如果要是電腦端訪問的話,還是觸發這個肯定不成功。所以在最開始要先判斷下ua。根據ua來做出下一步動作。簡單的放下ua判斷代碼

var browser = {
    versions: function() {
        var u = navigator.userAgent, app = navigator.appVersion;
        return {     //移動終端瀏覽器版本信息
            trident: u.indexOf('Trident') > -1, //IE內核
            presto: u.indexOf('Presto') > -1, //opera內核
            webKit: u.indexOf('AppleWebKit') > -1, //蘋果、谷歌內核
            gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內核
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否爲移動終端
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端
            android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android終端或uc瀏覽器
            iPhone: u.indexOf('iPhone') > -1, //是否爲iPhone或者QQHD瀏覽器
            iPad: u.indexOf('iPad') > -1, //是否iPad
            webApp: u.indexOf('Safari') == -1, //是否web應該程序,沒有頭部與底部
            qq: u.indexOf('MQQBrowser') > -1,//QQ瀏覽器
            uc: u.indexOf('UCBrowser') > -1// UC瀏覽器

        };
    } (),
    language: (navigator.browserLanguage || navigator.language).toLowerCase()
}
// 先判斷是否是PC,如果是PC端 就直接使用鏈接來分享
        if (browser.versions.mobile || browser.versions.android || browser.versions.ios){
            // if (browser.versions.qq && command==='qqFriend' || command==='qZone'){
            //     throw new Error;
            // }
            nativeShare.call(command)
        }else{
            // 使用原鏈接分享
            location.assign(e)
        }

效果

最後測試了幾個瀏覽器分享效果

瀏覽器 華爲自帶 X瀏覽器 模擬器自帶 模擬中QQ瀏覽器 APK內置
QQ好友 N Y Y Y Y
QQ空間 N Y Y Y Y
微信朋友圈 Y N N Y N

image

image

看來QQ瀏覽器果然通過原生的內置分享api都能達到分享喚起,但是在其他瀏覽器就有部分不兼容了。後面有需要在繼續調整優化吧,

Reference

H5喚起APP指南 https://suanmei.github.io/2018/08/23/h5_call_app/

h5喚起app http://echozq.github.io/echo-blog/2015/11/13/callapp.html

兼容是重點


作者:二歪求知iSk2y
鏈接:https://www.jianshu.com/p/500f4be528e3
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

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