微信打开本地app

来源:互联网 发布:制造业 数据分析部门 编辑:程序博客网 时间:2024/04/30 14:28

微信打开本地APP

最近需要实现一个需求:本地智能设备检测到事件后推送给服务器。服务器将相应事件推送给关注了公众号的微信,而用户可点击相应推送打开本地APP。

1 实现基础

主要涉及3个技术:

  1. URL Schemes
  2. 微信测试号推送
  3. 内网映射

1.1 URL Schemes 介绍

scheme是一种页面内跳转协议

  • 通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;
  • 通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面。
  • 可以通过H5页面跳转页面等。

1.2 微信测试号推送

通过微信公众平台申请测试号,此部分可通过申请测试号,让用户关注测试号,获得用户相应微信号。在服务器记录用户绑定的设备及微信号。当服务器检测到事件发生时,就调用相应推送模板API,将消息推送给相应用户。

1.3内网映射

微信测试号需要检测到你服务器资源,而在内网部署的服务器是在微信测试号后台设置相应接口的。所以需要将相应资源通过内网映射软件映射到公网。

2 URL Schemes使用

2.1 测试浏览器对URL Schemes支持情况

苹果可以直接在safiar中输入参考资料中提供URL观察应用是否启动。(本人未测) 安卓端浏览器地址栏均集成了搜索,输入URL极大可能会跳转到搜索界面,所以需要写个html界面进行测试。

2.2本地安卓app添加对URL Schemes支持

URL需配置在LAUNCHER对应的Activity下添加

<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="smarthomeapp" android:host="smarthome.app" android:pathPrefix="/parameter"/></intent-filter>

注意:如果需要配置能被js调起,一定要配置下面这句

<category android:name="android.intent.category.BROWSABLE">

比较关键的配置:

<data android:scheme="smarthomeapp" android:host="smarthome.app" android:pathPrefix="/parameter"/>

android:scheme=”smarthomeapp” 启动APP即可smarthomeapp://

后面参数为通过URL Scheme向app传递参数以便APP执行特定功能。但实际使用时,发现需要填完才能启动 即window.location = “smarthomeapp://smarthome.app/parameter”;

感谢app团队提供修改后的app及参考资料中分享知识网友。

2.3 IOS添加对URL Schemes支持

  • 每一个项目里面都会有一个info.plist配置文件。找到info.plist,右键选择Add Row,然后选择URL types。
  • 添加完URL types,点击展开。右键选择Add Row,添加URL Schemes
  • 设置URL Schemes为smarthomeapp 详情请参考2.5 IOS 参考设置

2.4 测试

  • 苹果可以直接在safiar中输入参考资料中提供URL观察应用是否启动。 如:smarthomeapp://
  • 安卓同样需要编写html实现测试 如window.location = “smarthomeapp://smarthome.app/parameter”;

2.5参考资料

常用URL Schemes

  • “taobao://”;淘宝
  • “weixin://”;微信
  • “mqq://”;qq
  • “openApp.jdMobile://”;京东
  • “alipayqr://”;支付宝

相关参考链接(感谢分享知识的大佬们)

  • 安卓URL Schemes设置可参考:http://blog.csdn.net/xc765926174/article/details/51397847
  • 苹果URL Schemes设置可参考:http://blog.csdn.net/sevenquan/article/details/54342281
  • URL Schemes 深入了解可参考:https://sspai.com/post/315

3 微信推送流程

3.1 内网映射

nohup ./ngrok -config=ngrok.cfg -subdomain xxx(想映射地址址名)80 &

成功后会打印:
Version 1.7/1.7
Forwarding http://XXX.tunnel.qydev.com -> 127.0.0.1:80
Forwarding https://XXX.tunnel.qydev.com -> 127.0.0.1:80
Web Interface 127.0.0.1:4040

Avg Conn Time 0.00ms
以上即实现将我们内网服务器端口映射成公网一个网址。
注此软件有开源版本有内存泄露问题

3.2 微信推送的基础设置

微信推送涉及到一部分微信公众号知识,这里只简单介绍下用到的部分信息。详细需查阅开发手册
微信测试号申请平台:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

  1. 得到后台的appID 及appsecret
  2. 填写服务器微信路由的URL 及 自己定义的Token
  3. 微信关注测试后即可在后台看到微信的OpenID,通过相应API 也可以在程序中得到。公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)
  4. 在微信公众号后台定义相应推送模板
  5. 程序中调用提供的sendTemplate

    function (openid, templateId, dest, data, callback, callback2) 填入相应的要推送微信用户id,要推送的模板id,跳转链接地址及相应回调即可实现推送。

实现流程图如下:

3.3 微信通过链接打开app

3.3.1 微信打开本地app方案分析

由于微信浏览器已经封禁了大部分URL Schemes接口,所以这对微信通过 URL Schemes 打开本地app造成很大的麻烦。

方案1:使用第三方工具openinstall

因为该工具是公司推出后面使用可能会涉及到一系列问题所以并没有采用。

方案2:

通过浏览器打开特定URL scheme即可实现唤醒。但微信内部禁用URL scheme接口
查阅资料可得:可以通过应用宝来实现打开本地app,即跳转到应用宝要打开应用的下载界面
如果已经下载就会直接打开
但是因为是测试app并没有上架。

最终采用了方案3:

最后采用了 通过手动点击微信浏览器右上角的+号选择从浏览器打开实现功能。

相关参考链接:http://www.openinstall.io/content_guide.html

3.3.2 实现流程

实现流程图:

技术点1: 判断是否在微信中。

function isWeiXin(){             var ua = window.navigator.userAgent.toLowerCase();             if(ua.match(/MicroMessenger/i) == 'micromessenger'){                 return true;             }else{                 return false;             } }

通过JavaScript获取浏览器信息进行判断

技术点2: 微信在浏览器中打开的遮罩代码。

参考文章:http://caibaojian.com/weixin-tip3.html

html:

 <div class="wxtip" id="JweixinTip"> <span class="wxtip-icon"></span> <p class="wxtip-txt">点击右上角<br/>选择在浏览器中打开</p>

ccs样式:

.wxtip{background: rgba(0,0,0,0.8); text-align: center; position: fixed; left:0; top: 0; width: 100%; height: 100%; z-index: 998; display: none;}.wxtip-icon{width: 52px; height: 67px; background: url(weixin-tip.png) no-repeat; display: block; position: absolute; right: 20px; top: 20px;}.wxtip-txt{margin-top: 107px; color: #fff; font-size: 16px; line-height: 1.5;}

JavaScript:

window.event? window.event.returnValue = false : e.preventDefault();document.getElementById('JweixinTip').style.display='block';

技术点3:判断手机操作系统

function getSystem(){                 if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {                    return "IOS";                    //callback(null, "iPhone");                    //window.location.href ="iPhone.html";                } else if (/(Android)/i.test(navigator.userAgent)) {                    return "Android";                                           //callback(null, "Android");                    //window.location.href ="Android.html";                } else {                    return "PC";                        //callback(null, "PC");-                };}

通过JavaScript获取浏览器信息进行判断(可能并不完善)

技术点4:判断是否本地安装app 没有安装给出下载链接

                            window.location = "smarthomeapp://smarthome.app/parameter";                            t = Date.now();                            setTimeout(function(){                                if (Date.now() - t < 2200) {                                    alert("检测到本地没有安装smarthome APP\n即将下载APP");                                    window.location = '/files/downloadapp?OS=Android';                                }                               }, 2000);

判断本地是否安装app,并不是按照字面意思去判断,而是通过URL Schemes去唤醒app,唤醒成功即认为已安装app,而一定时间内都没有唤醒成功即认为没有安装app,从而跳转下载界面。if()语句的作用是在定时2秒去判断app是否打开。分析:JavaScript代码在浏览器切换到后台(app打开了),代码会暂停。而setTimeout机制则并不会受到影响,如果app打开了即表现为,浏览器2s后在后台也能触发setTimeout的function。但因为JavaScript语句在后台暂停执行,即表现为程序暂停在了if语句前,当我们又切换会浏览器会执行Date.now()语句获取当前时间,很明显当前时间已经大于2.2s了,所以不再跳转到下载界面。

技术点5:

我们可以通过express提供的res.download(文件路径)来通过下载。即:

res.download("./public/smarthomeAPP.apk", function(err){            return err ? err : null;});