Android H5拉起 app

2024-05-28 11:38
文章标签 android app h5 拉起

本文主要是介绍Android H5拉起 app,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

工作较忙,暂做记录,稍后整理

需求:打开特定链接后能直接拉起本地 app,

实现效果:打开网页后,网页初始化时 js 代码 call native app, 系统显示是否打开相应 app 的弹窗

H5 拉起 App

  • 1. 参考 `openinstall` 实现方式:
  • 2. 最后采用的方案
  • 3. 参考链接

1. 参考 openinstall 实现方式:

<script type="text/javascript">//OpenInstall初始化时将与OpenInstall服务器交互,应尽可能早的调用/*web页面向app传递的json数据(json string/js Object),应用被拉起或是首次安装时,通过相应的android/ios api可以获取此数据*/var data = OpenInstall.parseUrlParams();///openinstall.js中提供的工具函数,解析url中的所有查询参数new OpenInstall({/*appKey必选参数,平台为每个应用分配的ID*/appKey : "mo3xfe",_pkgId:"3559314099997391369",/*自定义遮罩的html*///mask:function(){//  return "<div id='_shadow' style='position:fixed;left:0;top:0;background:rgba(0,255,0,0.5);filter:alpha(opacity=50);width:100%;height:100%;z-index:10000;'></div>"//},/*初始化完成的回调函数,可选*/onready : function() {/*在app已安装的情况尝试拉起app*/this.schemeWakeup();/*用户点击某个按钮时(假定按钮id为downloadButton),安装app*/var m = this, button = document.getElementById("downloadButton");button.style.visibility = "visible";button.onclick = function() {m.wakeupOrInstall();return false;}}}, data);</script>
  • 最后使用的 js 代码

2. 最后采用的方案

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover"><title>Sample for app deep link</title><style>body {text-align: center;}.btn {word-break: normal;tab-size: 4;-webkit-font-smoothing: antialiased;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);overflow-wrap: break-word;background-repeat: no-repeat;box-sizing: inherit;margin: 0;font: inherit;overflow: visible;border-style: none;cursor: pointer;align-items: center;border-radius: 4px;display: inline-flex;flex: 0 0 auto;font-weight: 500;letter-spacing: .0892857143em;justify-content: center;outline: 0;position: relative;text-decoration: none;text-indent: .0892857143em;text-transform: uppercase;transition-duration: .28s;transition-property: box-shadow, transform, opacity;transition-timing-function: cubic-bezier(.4, 0, .2, 1);user-select: none;vertical-align: middle;white-space: nowrap;color: #fff !important;box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12) !important;font-size: .875rem;will-change: box-shadow;background-color: #6200ea !important;border-color: #6200ea !important;height: 36px;min-width: 64px;padding: 0 16px;}</style><script type="text/javascript">(function webpackUniversalModuleDefinition(root, factory) {if (typeof exports === 'object' && typeof module === 'object')module.exports = factory();else if (typeof define === 'function' && define.amd)define([], factory);else if (typeof exports === 'object')exports["AppDeepLink"] = factory();elseroot["AppDeepLink"] = factory();})(window, function () {return /******/ (function (modules) { // webpackBootstrap/******/ // The module cache/******/var installedModules = {};/******//******/ // The require function/******/function __webpack_require__(moduleId) {/******//******/ // Check if module is in cache/******/if (installedModules[moduleId]) {/******/return installedModules[moduleId].exports;/******/}/******/ // Create a new module (and put it into the cache)/******/var module = installedModules[moduleId] = {/******/i: moduleId,/******/l: false,/******/exports: {}/******/};/******//******/ // Execute the module function/******/modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******//******/ // Flag the module as loaded/******/module.l = true;/******//******/ // Return the exports of the module/******/return module.exports;/******/}/******//******//******/ // expose the modules object (__webpack_modules__)/******/__webpack_require__.m = modules;/******//******/ // expose the module cache/******/__webpack_require__.c = installedModules;/******//******/ // define getter function for harmony exports/******/__webpack_require__.d = function (exports, name, getter) {/******/if (!__webpack_require__.o(exports, name)) {/******/Object.defineProperty(exports, name, {enumerable: true,get: getter});/******/}/******/};/******//******/ // define __esModule on exports/******/__webpack_require__.r = function (exports) {/******/if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {/******/Object.defineProperty(exports, Symbol.toStringTag, {value: 'Module'});/******/}/******/Object.defineProperty(exports, '__esModule', {value: true});/******/};/******//******/ // create a fake namespace object/******/ // mode & 1: value is a module id, require it/******/ // mode & 2: merge all properties of value into the ns/******/ // mode & 4: return value when already ns object/******/ // mode & 8|1: behave like require/******/__webpack_require__.t = function (value, mode) {/******/if (mode & 1) value = __webpack_require__(value);/******/if (mode & 8) return value;/******/if ((mode & 4) && typeof value === 'object' && value && value.__esModule)return value;/******/var ns = Object.create(null);/******/__webpack_require__.r(ns);/******/Object.defineProperty(ns, 'default', {enumerable: true,value: value});/******/if (mode & 2 && typeof value != 'string')for (var key in value) __webpack_require__.d(ns, key, function (key) {return value[key];}.bind(null, key));/******/return ns;/******/};/******//******/ // getDefaultExport function for compatibility with non-harmony modules/******/__webpack_require__.n = function (module) {/******/var getter = module && module.__esModule ?/******/function getDefault() {return module['default'];} :/******/function getModuleExports() {return module;};/******/__webpack_require__.d(getter, 'a', getter);/******/return getter;/******/};/******//******/ // Object.prototype.hasOwnProperty.call/******/__webpack_require__.o = function (object, property) {return Object.prototype.hasOwnProperty.call(object, property);};/******//******/ // __webpack_public_path__/******/__webpack_require__.p = "";/******//******//******/ // Load entry module and return exports/******/return __webpack_require__(__webpack_require__.s = 0);/******/})/************************************************************************//******/([/* 0 *//***/(function (module, exports, __webpack_require__) {const agent = __webpack_require__(1);const tool = __webpack_require__(2);const browserGuideTpl ='<div style=\'position:fixed;left:0;top:0;background:rgba(0,0,0,0.5);filter:alpha(opacity=50);width:100%;height:100%;z-index:10000;\'><div style=\'text-align:right;margin-top:1%;margin-right:5%;\'><img style=\'width:70%; margin:0 auto;\' src=\'https://res.zijizhang.com/img/android-brower-tip.png\'/></div></div>';const platformUnSupportMsg = 'Do not support this platform';const err = (errorHandler, msg) => {if (errorHandler) {return errorHandler(msg)}throw msg};const wakeUpOrInstallIos = (ios, onError) => {if (!ios) {return err(onError, platformUnSupportMsg)}const {ulink,scheme,downloadUrl} = ios;if (ulink) {return tool.loc(ulink)}let delayTs = 100;if (scheme) {delayTs = 2000;if (agent.isWechat) {tool.createEl(browserGuideTpl);return}tool.loc(scheme);// if (downloadUrl) {//     const openTs = +new Date();//     let timer = setTimeout(() => {//         const now = +new Date();//         if (now - openTs < 2200) {//             tool.loc(downloadUrl);//         }//         clearTimeout(timer)//     }, 2000);// }// return;}if (downloadUrl) {if (!/itms-app|apps.apple.com/.test(downloadUrl)) {tool.createEl(browserGuideTpl);return}tool.delayRun(() => {tool.loc(downloadUrl)}, delayTs)}};const wakeUpOrInstallAndroid = (android, onError) => {if (!android) {return err(onError, platformUnSupportMsg)}const {scheme,downloadUrl} = android;if (!scheme && !downloadUrl) {return}if (agent.isWechat) {if (scheme || (downloadUrl && !/app.qq.com/.test(downloadUrl))) {tool.createEl(browserGuideTpl);return}}if (downloadUrl) {let delayTs = agent.isMiui ? 1000 : 300;tool.delayRun(() => {tool.loc(downloadUrl)}, delayTs)}if (scheme) {tool.elClick(scheme);}};const wakeUpOrInstall = (param) => {const {android,ios,onError} = param || {};if (agent.isIOS) {return wakeUpOrInstallIos(ios, onError)}if (agent.isAndroid) {return wakeUpOrInstallAndroid(android, onError)}err(onError, platformUnSupportMsg);};module.exports = {wakeUpOrInstall};/***/}),/* 1 *//***/(function (module, exports) {const UA = window.navigator.userAgent.toLowerCase();module.exports = {UA,isAndroid: UA && /android|miui/.test(UA),isIOS: UA && /iphone|ipad|ipod|ios/.test(UA),isPC: UA && !exports.isAndroid && !exports.isIOS,isMiui: UA && /miui/.test(UA),isAlipay: UA && /alipayclient/.test(UA),isWechat: UA && /(micromessenger)/.test(UA),isWeibo: UA && /weibo/.test(UA),isQQ: UA && /qq\/([\d\\.]+)*/.test(UA),isFacebook: UA && /fban|fbav/.test(UA),isInstagram: UA && /instagram/.test(UA),};/***/}),/* 2 *//***/(function (module, exports) {const elClick = (url) => {const el = document.createElement("a");el.style.display = "none";el.href = url;document.body.appendChild(el);el.click()};const frm = (url) => {const el = document.createElement("iframe");el.style.display = "none";el.style.visibility = "hidden";el.src = url;document.body.appendChild(el)};const loc = (url) => {window.location.href = url};const open = (url) => {window.open(url)};const delayRun = (callback, timeout) => {let r, i;void 0 !== document.hidden ?(r = "hidden", i = "visibilitychange") :void 0 !== document.msHidden ?(r = "msHidden", i = "msvisibilitychange") :void 0 !== document.webkitHidden && (r = "webkitHidden", i ="webkitvisibilitychange");let timeoutTask = setTimeout(() => {null == timeoutTask || document[r] || (callback(), timeoutTask =null)}, timeout);let logic = () => {null != timeoutTask && document[r] && (clearTimeout(timeoutTask),timeoutTask = null, document.removeEventListener(i, logic))};i && document.addEventListener(i, logic, !1)};const createEl = (elStr) => {let el = document.createElement('div');el.innerHTML = elStr;let currEl = el.children[0];const evt = () => {document.body.removeChild(el);};if (currEl.addEventListener) {currEl.addEventListener('click', evt);} else {currEl.onclick = evt;}document.body.appendChild(el)};module.exports = {elClick,frm,loc,open,delayRun,createEl};/***/})/******/]);});</script>
</head><body><button class="btn" onclick="download()">Wake up or install</button>
</body>
<script>(function () {download()})();function download() {AppDeepLink.wakeUpOrInstall({android: {scheme: 'scheme',downloadUrl: 'downloadUrl'}});}
</script></html>

3. 参考链接

  • APP唤起那点破事

  • h5唤起app – 三种唤起方案

  • H5唤起APP指南(附开源唤端库 – callapp-lib)

    • 不能在页面刚打开时自动唤醒,我已实现,回头建议加入此 lib
  • h5 唤起 APP

  • H5 唤醒 APP 解决方案

  • H5唤醒App方式汇总

  • 移动浏览器H5页面通过scheme打开本地应用

  • h5启动原生APP总结

  • 移动浏览器H5页面通过scheme打开本地应用

  • js 通过schema协议拉起本地app

  • 集成 openinstall 之后它们给的测试链接,可参考页面的 js 代码

这篇关于Android H5拉起 app的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010461

相关文章

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel