H5喚起APP進(jìn)行分享的嘗試

H5喚起APP進(jìn)行分享

最近很久沒有寫blog和note,倒是過家家的開發(fā)日志簡單草草寫了一點(diǎn)。這次記錄下這個(gè)學(xué)習(xí)過程

由來

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

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

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

疑問?

然后我平時(shí)留意幾大互聯(lián)網(wǎng)的巨頭的h5頁面,他也是可以進(jìn)行APP喚起的,這到底是怎么做到的?

不過這種情況分為兩種:

  1. 喚起自己產(chǎn)品的APP

  2. 喚起第三方APP

    image
image

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

分析實(shí)現(xiàn)方式

經(jīng)過我 面向搜索引擎 的一頓操作,了解到一些資料和方式,其中要實(shí)現(xiàn)在h5喚起APP的主要采用

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

URLScheme

URL Scheme 是什么

我們來看一下 URL 的組成:

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

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

就像給服務(wù)器資源分配一個(gè) URL,以便我們?nèi)ピL問它一樣,我們同樣也可以給手機(jī)APP分配一個(gè)特殊格式的 URL,用來訪問這個(gè)APP或者這個(gè)APP中的某個(gè)功能(來實(shí)現(xiàn)通信)。APP得有一個(gè)標(biāo)識,好讓我們可以定位到它,它就是 URL 的 Scheme 部分。

常用APP的 URL Scheme

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

URL Scheme 語法

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

     行為(應(yīng)用的某個(gè)功能)    
            |
scheme://[path][?query]
   |               |
應(yīng)用標(biāo)識       功能需要的參數(shù)

搜集到的常用Scheme

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

我進(jìn)入深坑

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

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

后來想想,也是挺正常的,大多網(wǎng)站和企業(yè)只是想喚起自己的APP,那如何使用這些URL Scheme呢

大坑

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

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

    這些應(yīng)用能阻止喚端是因?yàn)樗鼈冎苯悠帘蔚袅?URL Scheme 。接下來可能就有看官疑惑了,微信中是可以打開大眾點(diǎn)評的呀,微博里面可以打開優(yōu)酷呀,那是如何實(shí)現(xiàn)的呢?

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

  • 騰訊應(yīng)用寶直接打開 APP 的某個(gè)功能

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

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

感覺騰訊應(yīng)用寶是個(gè)做文章的很地方,沒準(zhǔn)之后會嘗試下

瀏覽器的內(nèi)置分享原生分享

瀏覽器自帶有分享到微信和QQ的功能,但不是每個(gè)都提供接口來供網(wǎng)頁調(diào)用。即使有提供,瀏覽器暴露的api不一樣,各家有各家的規(guī)則和方式。

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

主要的瀏覽器有:

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

觸發(fā)方式

現(xiàn)在來說說觸發(fā)方式,大致上有三種:

iframe方案

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

在未安裝 app 的情況下,不會去跳轉(zhuǎn)錯(cuò)誤頁面。但是 iframe 在各個(gè)系統(tǒng)以及各個(gè)應(yīng)用中的兼容問題還是挺多的,我自己并沒有使用這種。

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

//創(chuàng)建一個(gè)隱藏的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方案的喚起原理是: 程序切換到后臺時(shí),計(jì)時(shí)器會被推遲(計(jì)時(shí)器不準(zhǔn)的又一種情況)。如果app被喚醒那么網(wǎng)頁必然就進(jìn)入了后臺,如果用戶從app切回來,那么時(shí)間一般會超過2s;若app沒有被喚起,那么網(wǎng)頁不會進(jìn)入后臺,setTimeout基本準(zhǔn)時(shí)觸發(fā),那么時(shí)間不會超過2s。

a標(biāo)簽喚起

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

上面這個(gè)a標(biāo)簽?zāi)憧梢宰约簢L試一下,是可以直接喚起的,a標(biāo)簽如果目標(biāo)scheme錯(cuò)誤,即應(yīng)用不存在也不會報(bào)錯(cuò)。

location.href跳轉(zhuǎn)

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

我自己大多使用click的方式配合location來進(jìn)行跳轉(zhuǎn),自己沒有在各大平臺和各個(gè)瀏覽器版本上做太多實(shí)驗(yàn),在一個(gè)博文中看到

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

某篇博文中對三種喚起方式進(jìn)行了測試

。X表示喚起失敗,√表示喚起成功
。紅色標(biāo)記表示進(jìn)入頁面直接喚起,綠色表示人工事件操作后喚起
。ios測試機(jī):iphone 6p;android測試機(jī):小米1s

iframe喚起app測試結(jié)果

圖片顯示

window.location.href喚起app測試結(jié)果

圖片顯示

a標(biāo)簽喚起app測試結(jié)果

圖片顯示

iframe和window.location.href喚起對比

圖片顯示

iframe、window.location.href和a標(biāo)簽喚起三者對比

圖片顯示

對比iframe喚起和location.href,我們可以發(fā)現(xiàn):

  1. 對于ios來說,location.href跳轉(zhuǎn)更合適,因?yàn)檫@種方式可以在Safari中成功喚起app。Safari作為iphone默認(rèn)瀏覽器其重要性就不用多說了,而對于微信和qq客戶端,ios中這兩種方式都沒有什么卵用==
  2. 對于Android來說,在進(jìn)入頁面直接喚起的情況下,iframe和location.href是一樣的,但是如果是事件驅(qū)動(dòng)的喚起,iframe喚起的表現(xiàn)比location.href要更好一點(diǎn)。
  3. 通過測試可以發(fā)現(xiàn),進(jìn)入頁面直接喚起和事件驅(qū)動(dòng)的喚起,對于很多瀏覽器,兩者的表現(xiàn)是不同的,簡單來說,直接喚起的失敗更多。

以上測試可能隨時(shí)間已經(jīng)有出入和變化,僅供參考

選擇

看了這些資料后,開始動(dòng)手對網(wǎng)站的分享功能再次二開,目前都是采用a標(biāo)簽進(jìn)行一個(gè)簡單的跳轉(zhuǎn),去對應(yīng)社交平臺的分享url的api接口提交各個(gè)參數(shù)。

image

嘗試

準(zhǔn)備先引入大佬的NativeShare輪子,因?yàn)槲以谒脑诰€demo嘗試了,我手機(jī)自帶瀏覽器、模擬器的自帶瀏覽器、模擬器的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);

        }

    })
})

對目前的各個(gè)a標(biāo)簽,在dom加載完成時(shí)添加一個(gè)click事件,阻止a標(biāo)簽的觸發(fā),然后把href地址記錄下來。然后再去觸發(fā)相應(yīng)的NativeShare中的call方法。

但是我發(fā)現(xiàn)在原生的瀏覽器里面竟然沒觸發(fā)。。那就做個(gè)降級處理吧。

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

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

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)

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

細(xì)節(jié)處理

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

var browser = {
    versions: function() {
        var u = navigator.userAgent, app = navigator.appVersion;
        return {     //移動(dòng)終端瀏覽器版本信息
            trident: u.indexOf('Trident') > -1, //IE內(nèi)核
            presto: u.indexOf('Presto') > -1, //opera內(nèi)核
            webKit: u.indexOf('AppleWebKit') > -1, //蘋果、谷歌內(nèi)核
            gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內(nèi)核
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否為移動(dòng)終端
            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應(yīng)該程序,沒有頭部與底部
            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)
        }

效果

最后測試了幾個(gè)瀏覽器分享效果

瀏覽器 華為自帶 X瀏覽器 模擬器自帶 模擬中QQ瀏覽器 APK內(nèi)置
QQ好友 N Y Y Y Y
QQ空間 N Y Y Y Y
微信朋友圈 Y N N Y N
image
image

看來QQ瀏覽器果然通過原生的內(nèi)置分享api都能達(dá)到分享喚起,但是在其他瀏覽器就有部分不兼容了。后面有需要在繼續(xù)調(diào)整優(yōu)化吧,

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

兼容是重點(diǎn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在移動(dòng)互聯(lián)網(wǎng),鏈接是比較重要的傳播媒質(zhì),但很多時(shí)候我們又希望用戶能夠回到APP中,這就要求APP可以通過瀏覽器或在...
    魚雨魚閱讀 3,357評論 3 17
  • 在移動(dòng)互聯(lián)網(wǎng),鏈接是比較重要的傳播媒質(zhì),但很多時(shí)候我們又希望用戶能夠回到APP中,這就要求APP可以通過瀏覽器或在...
    魔窗magicwindow閱讀 2,533評論 2 5
  • 移動(dòng)互聯(lián)網(wǎng)時(shí)代,“用戶增長”成為每個(gè)公司關(guān)注的重點(diǎn)話題。為了將更多用戶引導(dǎo)到客戶端內(nèi),產(chǎn)品經(jīng)理會習(xí)慣性地在網(wǎng)頁的各...
    宇曉閱讀 22,349評論 4 20
  • 入秋了,路上會遇到用小販用小貨車?yán)u芒果,和去年一樣,我會停下急匆匆的腳步,買幾個(gè)。一則自己愛吃芒果不過敏,二則...
    一畝三分甜閱讀 68,319評論 20 78
  • 燥熱的天,按耐不住寂寞,下起了雨,還不忘怒吼幾聲雷鳴。這是對夏的告別! 沒傘的人兒,駐留在地鐵(口),數(shù)著雨落,刷...
    sunhello閱讀 288評論 0 0

友情鏈接更多精彩內(nèi)容