背景
出于各种各样的原因,希望能够在小程序中拉起自己的APP,当APP未安装时跳转至苹果商店/微信下载页。
当前H5的唤醒APP实现过程
1.检测用户是否已经安装对应APP
用户点击跳转客户端按钮以后,调用微信JSBridgeAPI 'getInstallState',安卓传packageName,ios传packageUrl,检测是否已经安装所希望打开的APP,微信会返回 APP的安装情况
2.若用户还没有安装,ios通过window.location.href跳转至自己的下载中间页面,中间页再重定向到app store商店对应下载页面(其实把 app.apple/cn/id 这种格式的链接用window.location.href进行跳转也可以实现跳转到app store,多一层中间页可能是用于控制版本; 安卓则是调用微信JSBridgeAPI 'addDownloadTask',这时候会跳转到微信自带的下载页面,由用户确定是否进行下载。
3.若用户已安装APP,则调用微信JSBridge API launchApplication进行拉起
在微信小程序中拉起
1.通过webview内嵌原本就带有唤醒APP功能的H5来拉起APP: H5在微信打开会被注入window.WeixinJSBridge,而这也是H5拉端能力的基础;如果H5在小程序内嵌的H5中打开,也会被注入window.WeixinJSBridge,并且这个JSBridge保留着名字一样的api接口。如果此时仍用launchApplication拉起APP,可以在回调观察到调用结果是the permission value is offline verifying。原本发现个别H5仍能拉起APP,我以为是小程序后台配置中对这些域名特殊处理了,但经过实验发现并不是小程序后台配置的问题,而是这个域名本就在微信的白名单里面。此外,微信小程序内嵌H5在ios中也不能通过window.location.href的方式拉起app store(即使域名在白名单中)。所以如果已经在白名单,并且希望完整还原拉起APP的效果,需要改写ios拉起下载的方式,通过launchApplication接口和app store的scheme参数拉起苹果商店的对应下载页面。
2.原生小程序拉起APP:
首先定义以下几个场景
- 当小程序从 APP 打开的场景打开时(场景值 1069)
- 从其他小程序返回小程序(场景值1038)时
- 小程序从聊天顶部场景(场景值1089)中的「最近使用」内打开时
- 长按小程序右上角菜单唤出最近使用历史(场景值1090)打开时
- 发现栏小程序主入口,「最近使用」列表(场景值1001)打开时
- 浮窗(场景值1131、1187)打开时
这些场景的拉起APP能力遵循以下规律
简单来说,就是通过APP跳转到一个小程序时,可以通过这个小程序(包括之后自己再打开这个小程序的场景)拉起原本跳转到小程序的APP。但是如果是通过APP分享出去的小程序链接,对方打开以后点击拉起APP的按钮是没有办法拉起对方的APP的。
原生小程序拉起APP不需要通过JSBridge(当然,原生小程序也没有WeixinJSBridge,它的微信API在wx实例里), 它是通过<button open-type='launchApp'>
按钮返回到之前的app的。
3.通过webview内嵌与小程序有通信功能的H5来拉起APP:
之前提到的两种方案是H5利用微信H5能力拉起APP、小程序利用小程序能力拉起APP,那能否有一种方案能让webview内嵌H5利用小程序能力拉起APP呢(虽然小程序拉起APP能力现在也很有限了)?小程序<web-view>
组件只有bindmessage这一个属性可用于与H5通信,但是信息只有在小程序后退、组件销毁、分享时才能发送。使用示例:
小程序代码块
<web-view src="http://h5linck.com" bindmessage="handleMessage"></web-view>
handleMessage: function(event){ console.log(event) }
h5代码块
wx.miniProgram.navigateBack({ delta: 1 });
wx.miniProgram.postMessage({ data: '给小程序发送消息' })
可以看出,这个通信能力是非常弱的;如果说可以随时随地通信,那么就可以在小程序wxml中加入一个<button open-type='launchApp'>
按钮,它会被webview自动遮蔽,之后再通信让小程序模拟点击这个按钮(但是其实这里也很可能失败,因为微信可能会检测到按钮不是真实点击)完成唤起APP。
所以目前这种方案是完全不行的
总结
如果希望H5拉起APP,只能采用白名单机制,并且重写下载部分的代码;如果希望小程序拉起APP,这个也只有几个场景支持了;如果希望H5用小程序的能力拉起APP,那不现实。