鸿蒙OS开发实例:【Web网页】

news/发布时间2024/4/29 3:16:46

 背景

HarmonyOS平台通过Web控件可支持网页加载展示,Web在中是作为专项参考的。

本篇文章将从Android和iOS平台研发角度出发来实践学习API功能

说明

  1. 整个示例是以HarmonyOS开发文档网址作为加载目标
  2. 页面布局增加了三个按钮“后退”,“前进”, “刷新”

效果

Screenshot_20231130120249783.png

准备

  1. 请参照
鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术
鸿蒙技术文档开发知识更新库gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md在这。或+mau123789学习,是v喔

熟读HarmonyOS Web组件指导

搜狗高速浏览器截图20240326151547.png

2.创建一个Demo工程,选择Stage模型。

实践总结

  1. UA可以设置,但无法通过API拿到自己设置的UA值
  2. 文件可以下载,但用户没有控制权
  3. 用户无法控制定位权限申请
  4. Web控件当前需要将UA设置为Android或者iOS特征的UA,大部分主流网站没有适配鸿蒙Web
  5. 鸿蒙UA特征不明显 Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36

开始

页面容器设置为沉浸式

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage) {// 1.获取应用主窗口。let windowClass: window.Window = null;windowStage.getMainWindow((err, data) => {if (err.code) {console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));return;}windowClass = data;console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));// 2.实现沉浸式效果:设置导航栏、状态栏显示。windowClass.setWindowSystemBarEnable(['status','navigation'], (err) => {if (err.code) {console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));return;}console.info('Succeeded in setting the system bar to be visible.');});})//获取当前应用内最后显示的窗口,使用callback异步回调window.getLastWindow(this.context).then((result: window.Window) => {result.setWindowSystemBarEnable(['status', 'navigation'])result.setWindowLayoutFullScreen(true);})windowStage.loadContent('pages/Index', (err, data) => {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');});}}

创建WebView组件

文件路径

根目录/ets/entry/src/main/pages/WebView.ts

注册页面 main_pages.json

{"src": ["pages/Index","pages/WebView"]
}

功能实现

Cookie管理指导

网页调试

功能介绍
  1. 支持多窗口
  2. 多窗口返回关闭
  3. 加载进度提示
  4. 警告框,确认框,提示框
  5. 权限申请
  6. 输出调试日志
  7. 非http或https协议拦截
import web_webview from '@ohos.web.webview';
import router from '@ohos.router';
import common from '@ohos.app.ability.common';
import Url from '@ohos.url'web_webview.once("webInited", () => {console.log("setCookie")web_webview.WebCookieManager.setCookie("https://developer.harmonyos.com/", "author=harvey")
})//在同一page页有两个web组件。在WebComponent新开窗口时,会跳转到NewWebViewComp。
@CustomDialog
struct NewWebViewComp {private controller?: CustomDialogControllerprivate webviewController: web_webview.WebviewController = new web_webview.WebviewController()build() {Column() {Web({ src: "", controller: this.webviewController }).javaScriptAccess(true).multiWindowAccess(false).domStorageAccess(true).onWindowExit(() => {console.info("NewWebViewComp onWindowExit")if (this.controller) {this.controller.close()}})}}
}@Entry
@Component
struct Index {//www.useragentinfo.com// @State webURL: string = 'https://m.bilibili.com/'    //'https://developer.harmonyos.com/'// @State webURL: string = 'https://www.baidu.com'@State webURL: string = 'https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/start-overview-0000001478061421-V3?catalogVersion=V3'@State back: boolean = true@State forward: boolean = false@State showProgress: boolean = false@State currentProgress: number = 0@State buttonColorFocusColor: number = Color.Black@State buttonColorDisableColor: number = Color.Gray@State currentButtonColor: number = this.buttonColorFocusColorprivate webviewController: web_webview.WebviewController = new web_webview.WebviewController();private context = getContext(this) as common.UIAbilityContext;dialogController: CustomDialogController | null = nullaboutToAppear() {web_webview.WebviewController.setWebDebuggingAccess(true)let params = router.getParams()if (params) {this.webURL = params['targetUrl'];}}build() {Column() {Stack() {Web({ src: this.webURL, controller: this.webviewController }).width('100%').height('100%').userAgent('Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36 HarveyHarmonyOS/1.0.0').multiWindowAccess(true).javaScriptAccess(true).geolocationAccess(true).imageAccess(true).onlineImageAccess(true).domStorageAccess(true).fileAccess(true).mediaPlayGestureAccess(true).mixedMode(MixedMode.Compatible).onTitleReceive((info) => {console.log('标题栏: ' + info.title)}).onProgressChange((progress) => {console.log('当前加载进度 ' + progress.newProgress)this.currentProgress = progress.newProgressif (progress.newProgress >= 0 && progress.newProgress < 100) {this.showProgress = true} else if (progress.newProgress == 100) {this.showProgress = false}if (this.webviewController.accessForward()) {this.forward = truethis.currentButtonColor = this.buttonColorFocusColor} else {this.forward = falsethis.currentButtonColor = this.buttonColorDisableColor}console.log('userAgent: ' + this.webviewController.getUserAgent())}).onErrorReceive((error) => {console.log(error.request.getRequestUrl())console.log(JSON.stringify(error.error))}).onHttpErrorReceive((error) => {console.log(JSON.stringify(error.response))}).onSslErrorEventReceive((info) => {}).onRenderExited(() => {console.log('onRenderExited')}).onUrlLoadIntercept((info) => {if(!info.data.toString().toLowerCase().startsWith("https://") || !info.data.toString().toLowerCase().startsWith("https://")){console.log('拦截信息: ' + JSON.stringify(info))return true;}console.log('信息: ' + JSON.stringify(info))//false : 不拦截   true: 拦截return false}).onDownloadStart( (event) => {AlertDialog.show({title: event.url,message: event.url,primaryButton: {value: 'cancel',action: () => {}}})}).onAlert((event) => {AlertDialog.show({title: event.url,message: event.message,confirm: {value: 'onAlert',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true}).onConfirm((event) => {AlertDialog.show({title: event.url,message: event.message,confirm: {value: 'onConfirm',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true;}).onPrompt((event) => {AlertDialog.show({title: event.url,message: event.message,primaryButton: {value: 'cancel',action: () => {event.result.handleCancel()}},secondaryButton: {value: 'ok',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true;}).onConsole((msg) => {console.error('网页日志:' + JSON.stringify(msg.message.getMessage()))return true}).onWindowNew((event) => {console.log('新开window')if (!event.isAlert) {router.pushUrl({ url: 'custompages/WebView', params: {"targetUrl": event.targetUrl} }).then(() => {console.info('Succeeded in jumping to the second page.')}).catch((error) => {console.log(error)})} else {if (this.dialogController) {this.dialogController.close()}let popController: web_webview.WebviewController = new web_webview.WebviewController()this.dialogController = new CustomDialogController({builder: NewWebViewComp({ webviewController: popController })})this.dialogController.open()//将新窗口对应WebviewController返回给Web内核。//如果不需要打开新窗口请调用event.handler.setWebController接口设置成null。//若不调用event.handler.setWebController接口,会造成render进程阻塞。event.handler.setWebController(popController)}}).onWindowExit(() => {console.log('已推出window')}).onGeolocationHide(() => {console.log('geo隐藏')}).onGeolocationShow((info) => {info.geolocation.invoke(info.origin, false, false)console.log(info.origin + ' 有定位需求')}).onPageBegin((info) => {console.error(info.url)let host = Url.URL.parseURL(info.url).hosttry {let cookie = web_webview.WebCookieManager.getCookie(host)console.log('Bcookie: ' + cookie)} catch (e) {console.error(e)}}).onPageEnd((info) => {let host = Url.URL.parseURL(info.url).hosttry {let cookie = web_webview.WebCookieManager.getCookie(host)console.log('Bcookie: ' + cookie)} catch (e) {console.error(e + ' ' + info.url)}}).onBeforeUnload((info) => {return false}).onRefreshAccessedHistory((info) => {}).onResourceLoad(() => {}).onFullScreenEnter((info) => {}).onFullScreenExit(() => {}).onPermissionRequest((event) => {AlertDialog.show({title: 'title',message: event.request.getAccessibleResource()[0],primaryButton: {value: 'deny',action: () => {event.request.deny()}},secondaryButton: {value: 'onConfirm',action: () => {event.request.grant(event.request.getAccessibleResource())}},cancel: () => {event.request.deny()}})}).onInterceptKeyEvent((info) => {console.log(info.keyCode + ' ' + info.keyText)return false}).onPageVisible((info) => {console.log(info.url)})if (this.showProgress) {Progress({ value: this.currentProgress, total: 100, type: ProgressType.Linear }).width('100%').height(45)}}.height('93%').alignContent(Alignment.TopStart)Row() {Text('后退').fontSize(18).enabled(this.back).onClick(() => {if (this.webviewController.accessBackward()) {this.webviewController.backward()} else {if ("1" === router.getLength()) {this.context.terminateSelf()} else {router.back()}}}).width('30%').height('100%').textAlign(TextAlign.Center)Text('前进').fontSize(18).fontColor(this.currentButtonColor).onClick(() => {if (this.webviewController.accessForward()) {this.webviewController.forward()}}).width('30%').height('100%').textAlign(TextAlign.Center)Text('刷新').fontSize(18).fontColor(Color.Black).onClick(() => {this.webviewController.refresh()}).width('30%').height('100%').textAlign(TextAlign.Center)}.width('100%').height('5%').backgroundColor(Color.White).justifyContent(FlexAlign.SpaceBetween)}.width('100%').height('100%').padding({ top: px2vp(111) })}
}

鸿蒙知识持续更新中,关注我点赞不迷路喔!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/QReC/29697.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

地图可视化绘制 | R-tanaka/metR包 绘制3D阴影效果地图

今天我们再给大家介绍一个优秀的地图可视化绘制包-R-tanaka包&#xff08;用于绘制具有3d阴影效果的地图可视化作品&#xff09;&#xff0c;主要涉及的内容如下&#xff1a; R-tanaka包简介及样例样式 R-ggplot2绘制3d阴影地图 更多详细的数据可视化教程&#xff0c;可阅读…

机器视觉学习(七)—— 卷积、边缘和滤波器

目录 一、卷积运算 1.1 卷积运算的公式 1.2 卷积操作 二、垂直边缘与水平边缘 2.1 cv2.filter2D()函数 2.2 Sobel算子 三、滤波器 一、卷积运算 1.1 卷积运算的公式 卷积运算是一种图像处理的基本操作&#xff0c;常用于图像滤波、边缘检测等应用中。 卷积运算的基本思…

QT布局管理和空间提升为和空间间隔

QHBoxLayout&#xff1a;按照水平方向从左到右布局&#xff1b; QVBoxLayout&#xff1a;按照竖直方向从上到下布局&#xff1b; QGridLayout&#xff1a;在一个网格中进行布局&#xff0c;类似于HTML的table&#xff1b; 基本布局管理类包括&#xff1a;QBoxLayout、QGridL…

hbase启动错误-local host is“master:XXXX“ destination is:master

博主的安装前提&#xff1a; zookeeper安装完成&#xff0c;且启动成功 hdfs高可用安装&#xff0c;yarn高可用安装&#xff0c;且启动成功 报错原因&#xff1a;端口配置不对 解决方案&#xff1a; 输入&#xff1a;hdfs getconf -confKey fs.default.name 然后把相应的…

Redis命令-List命令

4.6 Redis命令-List命令 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与LinkedList类似&#xff1a; 有序元素可以重复插入和删除快查询速度一般 常用来存储一个有序数据&#xff…

Apache HBase(二)

目录 一、Apache HBase 1、HBase Shell操作 1.1、DDL创建修改表格 1、创建命名空间和表格 2、查看表格 3、修改表 4、删除表 1.2、DML写入读取数据 1、写入数据 2、读取数据 3、删除数据 2、大数据软件启动 一、Apache HBase 1、HBase Shell操作 先启动HBase。再…

SpringBoot项目启动成功,但是调用接口直接报NOT FOUND 404

问题描述 SpringBoot项目启动成功&#xff0c;但是调用接口直接报NOT FOUND 404 解决办法 启动类中ComponentScan(basePackages {“com.afclab”})中的扫包路径和项目路径不一样&#xff0c;导致扫不到Controller等组件&#xff0c;修改成和项目路径一样就可以解决&#xf…

解锁未知领域:探索Web3技术的无限可能性

随着数字化时代的持续发展&#xff0c;Web3技术作为下一代互联网的重要组成部分&#xff0c;正呈现出无限的创新可能性。本文将深入探索Web3技术所带来的无限可能性&#xff0c;揭示其在各个领域的应用前景和潜力。 1. 区块链技术的革命性 Web3的核心是区块链技术&#xff0c;…

Git版本管理使用手册 - 8 - 合并分支、解决冲突

合并整个开发分支 切换到本地test分支&#xff0c;选择右下角远程开发分支&#xff0c;选择Merge into Current。然后提交到远程test仓库。 合并某次提交的代码 当前工作区切换成test分支&#xff0c;选择远程仓库中的dev开发分支&#xff0c;选择需要合并的提交版本右击&a…

Leetcode146. LRU 缓存

Every day a Leetcode 题目来源&#xff1a;146. LRU 缓存 解法1&#xff1a;哈希表 链表 代码&#xff1a; /** lc appleetcode.cn id146 langcpp** [146] LRU 缓存*/// lc codestart class LRUCache { private:unordered_map<int, list<pair<int, int>>:…

【I.MX6ULL移植】Ubuntu-base根文件系统移植

1.下载Ubuntu16.04根文件系统 http://cdimage.ubuntu.com/ 1 2 3 4 5 2.解压ubuntu base 根文件系统 为了存放 ubuntu base 根文件系统&#xff0c;先在 PC 的 Ubuntu 系统中的 nfs 目录下创建一个名为 ubuntu_rootfs 的目录&#xff0c;命令如下&#xff1a; 【注意&…

Android应用程序的概念性描述

1.概述 Android 应用程序包含了工程文件、代码和各种资源&#xff0c;主要由 Java 语言编写&#xff0c;每一个应用程序将被编译成Android 的一个 Java 应用程序包&#xff08;*.apk&#xff09;。 由于 Android 系统本身是基于 Linux 操作系统运行的&#xff0c;因此 …

数据分析POWER BI之power query

1.导入数据 ctrla全选--数据--获取数据--其他来源--来自表格/区域 导入数据&#xff0c;进入编辑模式 2.整理与清除 清除&#xff1a;删除所选列的非打印字符 转换--格式--清除 修整&#xff1a;删除前面和后面的空格 转换---格式---修整&#xff08;修整后前面后面的空格没有了…

星光/宝骏/缤果/长安 车机CarPlay手机操作破解教程V2.0版本(无需笔记本、无需笔记本、无需笔记本)

之前写了个1.0版本&#xff0c;由于太局限&#xff0c;需要用到笔记本才能操作&#xff0c;很多车友反馈不方便。特此出个手机版教程&#xff0c;简单easy&#xff0c;妈妈再也不用担心我搞不定啦 一、准备工作 先卸载车机上的autokit 或者 智能互联 app&#xff0c;这步很关…

单片机之串口通信

目录 串口介绍 通信的基本概念 并行通信和串行通信 同步通信和异步通信 串行异步通信方式 串行同步通信方式 通信协议 单片机常见通信接口 串行通信三种模式 串口参数 传输速度 ​串口的连接 电平标准 串行口的组成 串口数据缓冲寄存器 串行口控制寄存器 串口…

STM32G473之flash存储结构汇总

STM32G4系列单片机&#xff0c;为32位的微控制器&#xff0c;理论上其内部寄存器地址最多支持4GB的命名及查找&#xff08;2的32次方&#xff0c;地址命名为0x00000000至0xFFFFFFFF&#xff09;。STM32官方对4GB的地址存储进行编号时&#xff0c;又分割成了8个block区域&#x…

《论文阅读》因果情绪蕴含的知识桥因果交互网络 AAAI 2023

《论文阅读》因果情绪蕴含的知识桥因果交互网络 AAAI 2023 前言简介任务定义特征提取并行知识桥接因果互动实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Knowledge-Bridged Causal Interac…

(免费分享)基于springboot,vue付费自习室系统带论文

在当今数字化时代&#xff0c;高效、便捷的管理系统成为了各行各业不可或缺的工具。特别是在教育服务领域&#xff0c;自习室作为学生和在职人员重要的学习场所&#xff0c;其预约和管理需求日益增长。为了满足这一市场需求&#xff0c;本文开发了这款基于微信小程序的付费自习…

游戏推广的新篇章:Xinstall助力实现全渠道效果统计与提升

随着游戏市场的日益繁荣&#xff0c;游戏推广已成为各大游戏公司争夺市场份额的关键环节。然而&#xff0c;面对众多推广渠道和复杂的用户行为&#xff0c;如何精准地评估推广效果、优化投放策略&#xff0c;成为了游戏推广人员亟待解决的问题。此时&#xff0c;Xinstall作为一…

B2902A是德科技B2902A精密型电源

181/2461/8938产品概述&#xff1a; Agilent B2902A 精密源/测量单元 (SMU) 是一款 2 通道、紧凑且经济高效的台式 SMU&#xff0c;能够源和测量电压和电流。它用途广泛&#xff0c;可以轻松、高精度地执行 I/V&#xff08;电流与电压&#xff09;测量。4 象限源和测量功能的集…
推荐文章