最近需要实现一个需求:本地智能设备检测到事件后推送给服务器。服务器将相应事件推送给关注了公众号的微信,而用户可点击相应推送打开本地APP。
主要涉及3个技术:
scheme是一种页面内跳转协议
通过微信公众平台申请测试号,此部分可通过申请测试号,让用户关注测试号,获得用户相应微信号。在服务器记录用户绑定的设备及微信号。当服务器检测到事件发生时,就调用相应推送模板API,将消息推送给相应用户。
微信测试号需要检测到你服务器资源,而在内网部署的服务器是在微信测试号后台设置相应接口的。所以需要将相应资源通过内网映射软件映射到公网。
苹果可以直接在safiar中输入参考资料中提供URL观察应用是否启动。(本人未测) 安卓端浏览器地址栏均集成了搜索,输入URL极大可能会跳转到搜索界面,所以需要写个html界面进行测试。
URL需配置在LAUNCHER对应的Activity下添加
注意:如果需要配置能被js调起,一定要配置下面这句
比较关键的配置:
android:scheme=”smarthomeapp” 启动APP即可smarthomeapp://
后面参数为通过URL Scheme向app传递参数以便APP执行特定功能。但实际使用时,发现需要填完才能启动 即window.location = “smarthomeapp://smarthome.app/parameter”;
感谢app团队提供修改后的app及参考资料中分享知识网友。
常用URL Schemes
相关参考链接(感谢分享知识的大佬们)
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
以上即实现将我们内网服务器端口映射成公网一个网址。
(注此软件有开源版本有内存泄露问题)
微信推送涉及到一部分微信公众号知识,这里只简单介绍下用到的部分信息。详细需查阅开发手册
微信测试号申请平台:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
程序中调用提供的sendTemplate
function (openid, templateId, dest, data, callback, callback2) 填入相应的要推送微信用户id,要推送的模板id,跳转链接地址及相应回调即可实现推送。
实现流程图如下:
由于微信浏览器已经封禁了大部分URL Schemes接口,所以这对微信通过 URL Schemes 打开本地app造成很大的麻烦。
方案1:使用第三方工具openinstall
因为该工具是公司推出后面使用可能会涉及到一系列问题所以并没有采用。
方案2:
通过浏览器打开特定URL scheme即可实现唤醒。但微信内部禁用URL scheme接口
查阅资料可得:可以通过应用宝来实现打开本地app,即跳转到应用宝要打开应用的下载界面
如果已经下载就会直接打开
但是因为是测试app并没有上架。
最终采用了方案3:
最后采用了 通过手动点击微信浏览器右上角的+号选择从浏览器打开实现功能。
相关参考链接:http://www.openinstall.io/content_guide.html
实现流程图:
技术点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:
点击右上角
选择在浏览器中打开
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;
});