H5 唤起 APP的解决方案

 H5 页面唤起APP或跳转到下载APP的某个链接地址。总结如下:

在 IOS 中, 系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件。 系统版本大于 8 以后,可以使用 universal Link 或 URL scheme 进行跳转。

// IOS 的唤起
function  vForIOS(urlScheme, storeURL, fallback, universalLink) {
     var  tid = deferFallback(TIMEOUT_IOS, storeURL, fallback);
     if  (parseInt(os.version, 10) < 8) {
         bindPagehideEvent(tid);
     else  {
         bindVisibilityChangeEvent(tid);
     }
     if  (parseInt(os.version, 10) > 8 && os.name ==  'iOS' ) {
         // 通过universalLink
         if  (universalLink === undefined) {
             universalLink = urlScheme;
         else  {
             clearTimeout(tid);
         }
         vLocation(universalLink);
     else  {
         vIframe(urlScheme);
     }
}

在安卓中, 安卓版本 4.4.4 以上机型的安卓自带浏览器、chrome 浏览器,需要通过 intent 跳转 【详情请见 https://developer.chrome.com/multidevice/android/intents】,其他浏览器大多数可通过 url scheme 唤起。但由于唤起APP后浏览器并无回调事件,我们很难判断是否已成功拉起APP,比较通用的解决办法是判断计时器是否变慢,若APP启动浏览器最小化入后台将会导致计时器变慢,即为实际事件间隔大于理想时间间隔。若未变慢则判断为未成功拉起APP,则跳转至下载地址。此判断代码如下:

function  deferFallback(timeout, storeURL, fallback) {
         var  clickedAt =  new  Date().getTime();
         return  setTimeout( function  () {
             var  now =  new  Date().getTime();
             if  (isPageVisible() && now - clickedAt < timeout + INTERVAL) {
                 fallback(storeURL);
             }
         }, timeout);
     }

安卓系统中,不同浏览器对唤起APP有严重的兼容性问题,主要处理方案有以下几种:

  1. 通过改变 window.location.href 
  2. 通过创建 iframe 并为其 src 赋值
  3. 通过 intent 
  4. 通过制造不可见 a 链接,并触发点击时间
// 打开页面的方式可能
     // 1. 通过改变location
     function  vLocation(urlScheme) {
         window.location.href = urlScheme;
     }
     // 2. 通过ifreame
     function  vIframe(urlScheme) {
         setTimeout( function  () {
             var  iframe = createHiddenIframe( 'appLauncher' );
             iframe.src = urlScheme;
         }, 100);
     }
     // 3. 通过intent
     function  vIntent(launchURI) {
         if  (browser.name ==  'Chrome' ) {
             move();
         else  {
             setTimeout(move, 100);
         }
 
         function  move() {
             // window.top.location.href = launchURI;
             window.location.href = launchURI
         }
     }
     // 3. 通过添加出发alink
     function  vAlink(launchURI) {
         var  aLink = document.createElement( "a" );
         aLink.setAttribute( "href" , launchURI);
         aLink.style.display =  "none" ;
         document.body.appendChild(aLink);
         var  event = document.createEvent( "HTMLEvents" );
         event.initEvent( "click" , !1, !1);
         aLink.dispatchEvent(event)
     }
  
     // IOS 中的 可见性事件
     function  bindPagehideEvent(tid) {
         window.addEventListener( 'pagehide' function  clear() {
             if  (isPageVisible()) {
                 clearTimeout(tid);
                 window.removeEventListener( 'pagehide' , clear);
             }
         });
     }
 
     function  bindVisibilityChangeEvent(tid) {
         document.addEventListener( 'visibilitychange' function  clear() {
             if  (isPageVisible()) {
                 clearTimeout(tid);
                 document.removeEventListener( 'visibilitychange' , clear);
             }
         });
     }
 
     function  isPageVisible() {
         var  attrNames = [ 'hidden' 'webkitHidden' ];
         for  ( var  i = 0, len = attrNames.length; i < len; i++) {
             if  ( typeof  document[attrNames[i]] !==  'undefined' ) {
                 return  !document[attrNames[i]];
             }
         }
         return  true ;
     }

已知的浏览器兼容问题:

  1.  上述 chrome 和 Android Browser 可以使用 intent 的方式拉起 app
  2.  QQ 浏览器 无法正确判断计时器是否变慢
  3.  微信浏览器 和 百度浏览器 无法唤起 app 除非加入其白名单
  4.  安卓4.4.4以前的 UC浏览器无法正确识别为 【安卓系统】需要单独设置判断条件


另: 研究京东唤起APP的代码时,其对百度浏览器做了如下操作,但我们对此的尝试并为成功,如下为其代码, 希望对后续研究此项的同学有帮助 :

function  ai(aA) {
     var  aD = ay(aA,  true );
     var  aB = aA.universalLinksUrl +  "/ul/ul.action?"  + aD;
     if  (navigator.userAgent.indexOf( "baidubrowser" ) >= 0) {
         window.location.href = aB
     else  {
         var  az = document.createElement( "a" );
         az.setAttribute( "href" , aB);
         az.style.display =  "none" ;
         document.body.appendChild(az);
         var  aC = document.createEvent( "HTMLEvents" );
         aC.initEvent( "click" , !1, !1);
         az.dispatchEvent(aC)
     }
}

转载于:https://www.cnblogs.com/yzhihao/p/8989195.html

<think>好的,我现在需要解决用户的问题:如何在鸿蒙系统中通过H5页面唤起原生App。首先,我需要仔细分析用户提供的引用内容,看看有没有相关的信息。 用户提供的引用中有几个相关的部分。引用[1]提到在鸿蒙原生App环境下,H5页面可以通过唤端协议实现唤端操作,示例使用了Scheme协议,比如harmonyphotos://com.huawei.gallery/module/album?page=1。这说明鸿蒙系统支持使用标准的Scheme协议来唤起应用。同时,引用[3]详细说明了H5页面跳转的方法,如果在H5中需要拉起其他应用,可以使用window.open(deepLink)。如果在应用内部,则用startAbility打开deepLink。这给了我两种不同的实现场景:在浏览器中的H5和鸿蒙应用内部的H5。 接下来,我需要考虑用户可能的场景,是鸿蒙应用内的Web组件加载的H5,还是在外部浏览器打开的H5。根据引用[3],两种情况处理方式不同。应用内H5可能需要使用startAbility方法,而外部H5则通过window.open触发Scheme。 然后,我需要验证这些方法的可行性。例如,在H5页面中,通过创建一个iframe或直接使用window.location.href来触发Scheme,这在安卓和iOS中是常见做法,但鸿蒙可能有所不同。引用[5]中的示例代码显示,安卓使用iframe加载Scheme,然后移除,这可能同样适用于鸿蒙的H5环境。 另外,处理未安装应用的情况也很重要。引用[1]提到,未安装时跳转到应用商店,这需要在前端检测是否成功唤起,如果超时则跳转下载页。这部分逻辑可能需要使用setTimeout来检测页面是否被挂起,如果一段时间后仍在当前页面,则跳转。 还需要考虑鸿蒙特有的Deep Link配置,比如在config.json中声明Scheme,这样系统才能识别并路由到对应应用。这部分可能需要开发者在原生应用中配置abilities的uris,如引用[3]中的示例。 最后,总结步骤:配置原生应用的Scheme,H5页面根据环境使用window.open或startAbility,处理未安装的情况,可能还需要考虑微信等浏览器中的限制,但用户的问题集中在鸿蒙系统,可能暂时不需要处理其他浏览器的问题。不过引用[4]和[5]提到微信中唤醒的问题,如果用户有相关需求,可能需要进一步处理,但当前问题可能不需要。 需要确保LaTeX格式正确,如行内公式用$...$,独立公式用$$...$$。用户的问题不涉及数学公式,但需要遵守系统指令。回答结构要清晰,分步骤说明,引用相关引用内容,并在末尾添加相关问题。</think>在鸿蒙系统中通过H5页面唤起原生App的实现方法可分为以下步骤: ### 一、基础原理 通过**URL Scheme协议**实现H5与原生应用的交互,鸿蒙系统支持标准Scheme格式: $$scheme://host/path?query$$ 例如:`harmonyapp://com.example.app/module/home?page=1`[^1] ### 二、实现步骤 #### 1. 原生应用配置 在`config.json`中声明Deep Link能力: ```json { "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ts", "uri": "harmonyapp://com.example.app" } ] } ``` 此配置允许系统识别`harmonyapp://`开头的Scheme[^3]。 #### 2. H5页面实现 **场景1:浏览器H5页面** ```javascript // 尝试唤起App const scheme = 'harmonyapp://com.example.app/module/home'; window.location.href = scheme; // 检测是否唤起成功(超时跳应用商店) setTimeout(() => { if (document.hidden || document.webkitHidden) return; window.location.href = '应用商店下载链接'; }, 2000); ``` **场景2:鸿蒙应用内Web组件加载的H5** ```typescript // 通过startAbility调用Deep Link import webview from '@ohos.web.webview'; webview.WebviewController.handleIntent({ intent: { action: 'ohos.intent.action.VIEW', uri: 'harmonyapp://com.example.app/module/home' } }); ``` 此方式需在Web组件中启用`javaScriptAccess`权限。 #### 3. 未安装应用的降级处理 ```javascript // 使用iframe兼容性方案(适用于安卓鸿蒙设备) const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = scheme; document.body.appendChild(iframe); setTimeout(() => { document.body.removeChild(iframe); window.location.href = 'https://appgallery.huawei.com/app/xxx'; }, 500); ``` 此方法可避免某些浏览器拦截直接跳转[^5]。 ### 三、注意事项 1. **Scheme白名单**:需在鸿蒙应用商店提交Scheme注册信息 2. **微信环境限制**:需引导用户通过浏览器打开(参考微信JS-SDK处理)[^4] 3. **参数传递**:URL长度需控制在1024字符以内
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值