js判断是否安装某个android app,没有安装下载该应用(websocket通信,监听窗口失去焦点事件)

简介: js判断如果安装了android app,则调起app, 没有安装,则直接下载应用。提供两种解决方案,一种是websocket通信,一种是监听页面失去焦点事件

现在经常有写场景需要提示用户下载app, 但是如果用户已经安装,我们希望是直接打开app。

实际上,js是没有判断app是否已经安装的方法的,我们只能曲线救国。

 

首先,我们需要有call起app的schema, 以及一个下载地址,比如:

var schema = 'myApp://main';
var downUrl = 'https://yourmain.com/downloadUrlTag';

一、使用websocket通信实现页端和app的通信

1. android app需要实现websocket的连接功能,开放一个特定的端口如8899;

2. 页端js建立websocket连接

 1 var download = function (schema, downUrl) {
 2     var ws = "ws://localhost:8899/websocket";
 3 
 4     function onMessage(event) {
 5         if (event.data != 'SUCCESS') {
 6             console.log(event.data + "!= 'SUCCESS'");
 7             window.location.href = downUrl;
 8         }
 9         socket.close();
10     }
11 
12     function onError(event) {
13         console.log("websocket error");
14         window.location.href = downUrl;
15     }
16 
17     function onOpen() {
18     }
19 
20     function onClose() {
21     }
22     // 判断浏览器
23     if (navigator.userAgent.match(/android/i) && (navigator.userAgent.match(/Chrome/) || navigator.userAgent.match(/Opera/))) {
24         if (window.WebSocket) {
25             try {
26                 socket = new WebSocket(ws);
27 } catch (ex) { 28 window.location.href = downUrl; 29 } 30 var message = ""; 31 socket.onmessage = onMessage; 32 socket.onopen = onOpen; 33 socket.onclose = onClose; 34 socket.onerror = onError; 35 36 if (socket.readyState == WebSocket.CONNECTING) { 37 setTimeout(function () { // websocket建立连接需要一段时间 38 if (socket.readyState == WebSocket.OPEN) { 39 if (schema != '') { 40 window.location.href = schema; 41 socket.send(message); 42 } 43 } else { 44 socket = new WebSocket(ws);
45 if (socket.readyState != WebSocket.OPEN) { 46 window.location.href = downUrl; 47 } 48 } 49 }, 1000); 50 } 51 } 52 } else { 53 window.location.href = downUrl; 54 } 55 };

当点击下载按钮的时候,调用download(schema,downUrl)方法即可。

但是这种方法存在一个严重的问题:当app不在进程中存活时,我们是无法成功call起的,这样,我们就需要在客户端做一些工作,让你的app一直存活在进程中。

二、监听当前页面是否失去焦点,来判断是否需要调用下载

首先,我们的想法是,当用户点击下载后,先尝试call起APP,使用setTimeout做延时处理,在延时中判断是否call起成功,如果不成功,则直接下载,我们如何认为call其成功呢,当一个应用被调用的时候,浏览器会被隐藏,那么当前页面会失去焦点。

首先,我们的想法是,当用户点击下载后,先尝试call起APP,使用setTimeout做延时处理,在延时中判断是否call起成功,如果不成功,则直接下载,我们如何认为call其成功呢,当一个应用被调用的时候,浏览器会被隐藏,那么当前页面会失去焦点。

var isBlur = false;
location.href = schema;
setTimeout(function() {
    if (!isBlur) {
      location.href = url;
    }
}, 1000);

那么如何来设置isBlur的值呢,这里提供两种方法:

1. 监听window的blur事件

// window 每次失去焦点
window.onblur = function() {
    console.log('失去焦点');
    isBlur = true;
};
     
// window 每次获得焦点
// window.onfocus = function() {
//    console.log('获得焦点');
//    isBlur = false;
// }

2. 自定义事件监听visibilityChange事件,来判断document的hidden属性,

简单写法:

document.addEventListener("visibilitychange", function(){
    console.log(document.hidden ? "失去焦点" : "获得焦点");
    isBlur = document.hidden;
});

兼容写法:

var hiddenProperty = 'hidden' in document ? 'hidden' :    
    'webkitHidden' in document ? 'webkitHidden' :    
    'mozHidden' in document ? 'mozHidden' :    
    null;
var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
var onVisibilityChange = function(){
    if (!document[hiddenProperty]) {    
        console.log('获得焦点'); 
        isBlur = false;
    } else {
        console.log('失去焦点');
        isBlur = true;
    }
}
document.addEventListener(visibilityChangeEvent, onVisibilityChange);

完整代码:

var download = function() {
    var isBlur = false;
    location.href = schema;
    setTimeout(function() {
        if (!isBlur) {
          location.href = url;
        }
    }, 1000);

    // window 每次失去焦点
    window.onblur = function() {
        console.log('失去焦点');
        isBlur = true;
    };

    var hiddenProperty = 'hidden' in document ? 'hidden' :    
        'webkitHidden' in document ? 'webkitHidden' :    
        'mozHidden' in document ? 'mozHidden' :    
        null;
    var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
    var onVisibilityChange = function(){
        if (document[hiddenProperty]) {    
            console.log('失去焦点');
            isBlur = true;
        }
    }
    document.addEventListener(visibilityChangeEvent, onVisibilityChange);
}

 

如果有哪里写的不对的,欢迎讨论!

 

目录
相关文章
|
7月前
|
移动开发 小程序 Android开发
基于 uni-app 开发的废品回收类多端应用功能与界面说明
本文将对一款基于 uni-app 开发的废品回收类多端应用,从多端支持范围、核心功能模块及部分界面展示进行客观说明,相关资源信息也将一并呈现。
238 0
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
923 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
机器学习/深度学习 存储 人工智能
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
12825 81
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
|
9月前
|
Java Shell Maven
【Azure Container App】构建Java应用镜像时候遇无法编译错误:ERROR [build 10/10] RUN ./mvnw.cmd dependency:go-offline -B -Dproduction package
在部署Java应用到Azure Container App时,构建镜像过程中出现错误:“./mvnw.cmd: No such file or directory”。尽管项目根目录包含mvnw和mvnw.cmd文件,但依然报错。问题出现在Dockerfile构建阶段执行`./mvnw dependency:go-offline`命令时,系统提示找不到可执行文件。经过排查,确认是mvnw文件内容异常所致。最终通过重新生成mvnw文件解决该问题,镜像成功构建。
481 1
|
9月前
|
存储 移动开发 监控
App Trace功能实战:一键拉起、快速安装与免提写邀请码的应用实践
App Trace系统通过一键拉起、快速安装和免提写邀请码三大功能,显著提升用户转化率、安装成功率和邀请注册率。结合深度技术实现与优化,助力公司用户增长,成为移动端核心基础设施。
|
11月前
|
搜索推荐 API UED
淘宝/天猫获得淘宝app商品详情原数据 API 返回值的应用
该API专注于商品信息整合与展示,提供基础信息抓取、多媒体内容整合等功能,助力实时同步商品数据,构建丰富的详情页。同时支持数据分析与市场洞察,包括销售趋势分析和竞品对比,优化库存与定价策略。此外,动态促销管理和个性化推荐系统可提升营销效果,而实时库存预警和评价数据可视化则显著增强用户体验,为用户决策提供透明依据,全面提升平台竞争力与用户满意度。
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
913 1
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
884 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
607 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。