【HarmonyOS】纯血鸿蒙真实项目开发---经验总结贴

项目场景:

将已有的Web网页接入到原生App。

涉及到一些网页回退、webviewController执行时机报错1710000001、位置定位数据获取拉起呼叫页面系统分享能力使用等。


问题描述

  1. 我们在选项卡组件中,在每个TabContent内容页中使用web组件加载网页。
    在最开始接入操作时,出现了Web组件加载某个页面,出现白屏、页面显示不出来。

解决方案:

经过对问题定位,发现需要设置是否开启文档对象模型存储接口(DOM Storage API)权限,默认未开启

Web({ src: this.webSrc, controller: this.webviewController }).domStorageAccess(true);

问题描述

  1. 每个TabContent内容页中使用web组件加载的网页,会涉及到一些页面的返回。如果是用户点击返回,网页端会进行回退操作,若用户使用侧滑返回网页端无法检测,会直接退出应用。

解决方案:

为了解决这个问题,我查阅到了有关侧滑返回或点击返回按钮时触发的自定义组件生命周期onBackPress(仅@Entry装饰的自定义组件生效)

@Entry
@Component
struct IndexComponent {@State textColor: Color = Color.Black;onBackPress() {this.textColor = Color.Red;console.info('IndexComponent onBackPress');}build() {Column() {Text('Hello World').fontColor(this.textColor).fontSize(30).margin(30)}.width('100%')}
}

返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理。

重点:在每个TabContent内容页加载的@Entry页面里,使用onBackPress是不生效的。我们只能在Tab所在的@Entry页面里,使用onBackPress才会生效。
为了控制TabContent中的Web页面回退,我们需要在Tab所在的页面里创建webviewController并将它传递给子组件。

父组件示例代码:
import { Page1, Page2 } from './Page1'@Entry
@Component
struct demo {//controller创建@Provide webcontroller1: webview.WebviewController = new webview.WebviewController();@Provide webcontroller2: webview.WebviewController = new webview.WebviewController();//返回逻辑onBackPress() {if (this.webcontroller1.accessStep(-1)) {this.webcontroller1.backward()// 执行用户自定义返回逻辑return true;} else if (this.webcontroller2.accessStep(-1)) {this.webcontroller2.backward();// 执行用户自定义返回逻辑return true;}  else {//执行系统默认返回逻辑,返回上一个page页return false;}}build() {Tabs(){TabContent(){Page1()}.tabBar('示例一')TabContent(){Page2()}.tabBar('示例二')}}
}
子组件示例代码:
import { webview } from '@kit.ArkWeb'@Entry
@Component
export struct Page1/2 {@Consume webcontroller1/2:webview.WebviewControllerbuild() {RelativeContainer() {Web({src:'https://www.baidu.com',controller:this.webcontroller1/2}).domStorageAccess(true)}.height('100%').width('100%')}
}

问题描述

  1. 因为每个Web页面的控制器是由父组件传入的,我们在使用时可能会出现710000001的报错,经查阅论坛发现,该报错原因是Web组件还未创建,我们的WebviewController控制器先执行了。

高发于在emitter中调用WebviewController控制器,尽量避免在emitter中使用,若必须使用参照下面的解决方案

解决方案:

解决这个问题,我并没有发现可以统一解决各种情况的方法。以下有多种解决方法:

  • [1] 在web组件的生命周期onPageEnd中使用控制器
  • [2]在onControllerAttached()这一回调方法中使用控制器
  • [3]在onDisAppear中使用控制器

问题描述

  1. 我们在一些场景下可能会需要用户的具体位置,以下是关于用户授权和逆地址编码转化,获取地址位置描述的方案总结。

解决方案:

获取用户位置授权onClickGetLocation = async () => {//首次权限请求if (this.step == 0) {const steps = await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(getContext(),['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'])this.step++}// 二次请求用户同意权限await this.checkPermissions()//获取当前位置let Location = await geoLocationManager.getCurrentLocation();await this.locationChange(Location)return JSON.stringify(this.returnInfor)}
若用户拒绝定位权限二次拉起async checkPermissions() {let grantStatus1: boolean = await WebUtils.checkPermissionGrant('ohos.permission.LOCATION') ===abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; // 获取精确定位权限状态let grantStatus2: boolean = await WebUtils.checkPermissionGrant('ohos.permission.APPROXIMATELY_LOCATION') ===abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; // 获取模糊定位权限状态// 精确定位权限只能跟模糊定位权限一起申请,或者已经有模糊定位权限才能申请精确定位权限if (!grantStatus2 && !grantStatus1) {// 用户拒绝二次拉起弹窗let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();let context: Context = getContext(this) as common.UIAbilityContext;await atManager.requestPermissionsFromUser(context,['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'])await atManager.requestPermissionOnSetting(context, ['ohos.permission.APPROXIMATELY_LOCATION']).then((data: Array<abilityAccessCtrl.GrantStatus>) => {console.info('data:' + JSON.stringify(data));}).catch((err: BusinessError) => {console.error('data:' + JSON.stringify(err));});} else {// 已经授权,可以继续访问目标操作return}}
/** * 定位回调 *///获取用户位置信息private async locationChange(location: geoLocationManager.Location) {if (location) {let reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = {'latitude': location.latitude, // 表示纬度信息,正值表示北纬,负值表示南纬。取值范围为-90到90。仅支持WGS84坐标系。'longitude': location.longitude, // 表示经度信息,正值表示东经,负值表是西经。取值范围为-180到180。仅支持WGS84坐标系。// 指定返回位置信息的最大个数。取值范围为大于等于0,推荐该值小于10。默认值是1。'maxItems': 1};// 逆地址编码转化,获取地址位置描述let data = await geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest);if (data) {if (data[0].locality !== undefined) {let res = data[0] as DeatilPositionViewPagelet placeName = res.placeNamelet countryName = res.countryNamelet provience = placeName.slice(0, placeName.indexOf('省') + 1)let city = placeName.slice(placeName.indexOf('省') + 1, placeName.indexOf('市') + 1)let area = placeName.slice(placeName.indexOf('市') + 1, placeName.indexOf('区') + 1)let deatil = placeName.slice(placeName.indexOf('区') + 1)let address = `${countryName} ${provience} ${city} ${area} ${deatil}`this.returnInfor = {address: address,longitude: res.longitude,latitude: res.latitude}}}}};
运行使用代码块
@Entry
@Component
export struct Page1 {@State returnInfor: returnDeatilPosition = {address: '',longitude: 0,latitude: 0}//判断是否为首次请求step = 0//写入上面三个方法build() {RelativeContainer() {Button(this.returnInfor).onclick(async()=>{await this.onClickGetLocation()})}.height('100%').width('100%')}
}

问题描述

  1. 我们在一些场景下可能会需要拉起用户的拨号界面,以下是关于拉起拨号的方案总结。

值得注意的是如果这里是混合开发需要的功能,我们可以把该方法写在.onLoadIntercept((event) => {})这个方法里面。具体相关使用自行查阅官方文档,较为简单不做赘述。

解决方案:

import { call, observer } from '@kit.TelephonyKit';
import { BusinessError } from '@kit.BasicServicesKit';// 调用查询能力接口@Entry
@Component
struct callphone {build() {Text('1111').onClick(()=>{let isSupport = call.hasVoiceCapability();if (isSupport) {// 如果设备支持呼叫能力,则继续跳转到拨号界面,并显示拨号的号码call.makeCall("4009609206", (err: BusinessError) => {});}})}
}

问题描述

  1. 我们在一些场景下可能会需要用到系统分享能力,以下是关于系统分享的方案总结。

解决方案:

async share(ctx: Context, url: string, title: string) {let shareData: systemShare.SharedData = new systemShare.SharedData({utd: uniformTypeDescriptor.UniformDataType.HYPERLINK,content: url,title: title,description: '分享此链接',});

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

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

相关文章

DeviceNet转Profinet网关如何革新污水处理行业!

DeviceNet转Profinet网关如何革新污水处理行业&#xff1f;在污水处理行业中&#xff0c;随着环保法规的日益严格和处理技术的不断进步&#xff0c;工业自动化技术的应用越来越广泛。特别是在提高生产效率、降低运营成本以及确保处理质量方面&#xff0c;自动化技术发挥着不可替…

(四)结合代码初步理解帧缓存(Frame Buffer)概念

帧缓存&#xff08;Framebuffer&#xff09;是图形渲染管线中的一个非常重要的概念&#xff0c;它用于存储渲染过程中产生的像素数据&#xff0c;并最终输出到显示器上。简单来说&#xff0c;帧缓存就是计算机图形中的“临时画布”&#xff0c;它储存渲染操作生成的图像数据&am…

58. Three.js案例-创建一个带有红蓝配置的半球光源的场景

58. Three.js案例-创建一个带有红蓝配置的半球光源的场景 实现效果 本案例展示了如何使用Three.js创建一个带有红蓝配置的半球光源的场景&#xff0c;并在其中添加一个旋转的球体。通过设置不同的光照参数&#xff0c;可以观察到球体表面材质的变化。 知识点 WebGLRenderer …

前端基础技术全解析:从HTML前端基础标签语言开始,逐步深入CSS样式修饰、JavaScript脚本控制、Ajax异步通信以及WebSocket持久通信

目录 前言&#xff1a; 1.前端技术html简单了解&#xff1a; 1.1HTML代码是由标签构成的。 1.2.HTML 文件基本结构 1.3.HTML 常见标签 标题标签: 段落标签: p 文本格式化标签 图片标签&#xff1a; 超链接标签: a 测试代码&#xff1a; 展示效果&#xff1a; 表单…

wireshark抓包工具新手使用教程

wireshark抓包工具新手入门使用教程 一、Wireshark软件安装二、Wireshark 抓包示范三、Wireshakr抓包界面四、Wireshark过滤器设置五、wireshark过滤器表达式的规则六、Wireshark抓包分析TCP三次握手七、Wireshark分析常用列标签格式 Wireshark是一款开源的网络协议分析工具&am…

中国省级产业结构高级化及合理化数据测算(2000-2023年)

一、数据介绍 数据名称&#xff1a;中国省级产业结构高级化、泰尔指数 数据年份&#xff1a;2000-2023年 数据范围&#xff1a;31个省份 数据来源&#xff1a;中国统计年鉴、国家统计局 数据整理&#xff1a;内含原始版本、线性插值版本、ARIMA填补版本 数据说明&#xf…

Qt 5.14.2 学习记录 —— 팔 QWidget 常用控件(3)

文章目录 1、cursor2、font3、toolTip4、focusPolicy5、styleSheeyt 1、cursor 改变鼠标光标形状。 在Qt Designer界面中&#xff0c;拖一个按钮过来&#xff0c;右边属性面用户可以自己改cursor属性。 代码方法&#xff0c;先拖一个按钮到界面上&#xff1a; #include <…

js:日期对象和dom节点

日期对象 事件对象在前端开发里经常用来表示日期&#xff1a; 可以获取当前系统的时间 实例化 使用new关键字来实例化一个对象&#xff1a; const date new Date()console.log(date); 获取当前时间 const date new Date(2008-8-8)console.log(date); 获取指定时间 写得…

minibatch时,损失如何记录

目录 minibatch时&#xff0c;损失如何记录 报错&#xff1a;UnboundLocalError: local variable coef referenced before assignment是什么回事 未溢出则不会报错&#xff0c;可以完整滴运行完成 indent 缩进 炫酷技能&#xff1a;一遍运行&#xff0c;一遍画图 实例1 解释…

力扣刷题:数组OJ篇(下)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 1.轮转数组&#xff08;1&#xff09;题目描述…

5G学习笔记之PNI-NPN

目录 1. 概述 2. CAG 2.1 CAG ID 2.2 CAG信息配置 3. 网络选择/网络重选&#xff0c;小区选择/小区重选 4. 接入和拥塞控制 1. 概述 PNI-NPN&#xff0c;Public Network Integrated NPN&#xff0c;公共网络集成的非公共网络&#xff0c;依赖于PLMN网络&#xff0c;使用 CAG&am…

el-table 自定义表头颜色

第一种方法&#xff1a;计算属性 <template><div><el-table:data"formData.detail"border stripehighlight-current-row:cell-style"{ text-align: center }":header-cell-style"headerCellStyle"><el-table-column fixed…

C#标识符和关键字

本文将学习两个重要的基本概念&#xff1a;标识符和关键字。 1. 标识符 我们继续秉承"从实践中学习"的理念&#xff0c;先来看一段代码&#xff0c;如代码清单3-1所示。 代码清单3-1 标识符 using System;namespace ProgrammingCSharp4 {class IdentifierSample{…

怎么管理电脑usb接口,分享四种USB端口管理方法

怎么管理电脑usb接口&#xff0c;分享四种USB端口管理方法 USB接口作为电脑重要的外部接口&#xff0c;方便了数据传输和设备连接。 然而&#xff0c;不加管理的USB接口也可能带来安全隐患&#xff0c;例如数据泄露、病毒传播等。 因此&#xff0c;有效管理电脑USB接口至关重…

从 TiDB 学习分布式数据库测试

前言 最近在研究数据库正确性测试相关的内容&#xff0c;恰好看到TiDB数据库在这方面的工作&#xff0c;很受启发&#xff0c;故写此文章。 推荐下一些TiDB官方好文章&#xff1a; 《分布式系统测试那些事儿 – 理念》https://cn.pingcap.com/blog/distributed-system-test-…

尚硅谷Vue3入门到实战 —— 04 OptionsAPI 与 CompositionAPI

我们看一下上一节的代码&#xff0c;如下&#xff1a; <template><div class"person"><h2>姓名&#xff1a; {{ name }}</h2><h2>年龄&#xff1a; {{ age }}</h2><button click"changeName">修改名字</but…

【物联网原理与运用】知识点总结(上)

目录 名词解释汇总 第一章 物联网概述 1.1物联网的基本概念及演进 1.2 物联网的内涵 1.3 物联网的特性——泛在性 1.4 物联网的基本特征与属性&#xff08;五大功能域&#xff09; 1.5 物联网的体系结构 1.6 物联网的关键技术 1.7 物联网的应用领域 第二章 感知与识别技术 2.1 …

Nginx:会话保持

会话保持 是指在负载均衡环境中,确保来自同一用户的多个请求都发送到同一个后端服务器。这通常用于那些需要记住用户状态或上下文的应用程序,例如购物车、登录状态等。 会话保持的重要性 用户体验:保证用户在整个会话期间的一致性体验,避免因不同服务器间的数据不同步导致…

SEO内容优化:如何通过用户需求赢得搜索引擎青睐?

在谷歌SEO优化中&#xff0c;内容一直是最重要的因素之一。但要想让内容真正发挥作用&#xff0c;关键在于满足用户需求&#xff0c;而不是简单地堆砌关键词。谷歌的算法越来越智能化&#xff0c;更注重用户体验和内容的实用性。 了解目标用户的需求。通过工具如Google Trends…

Clisoft SOS与CAD系统集成

Clisoft SOS与CAD系统集成 以下内容大部分来自官方文档&#xff0c;目前只用到与Cadence Virtuoso集成&#xff0c;其他还未用到&#xff0c;如有问题或相关建议&#xff0c;可以留言。 与Keysight ADS集成 更新SOS客户端配置文件sos.cfg&#xff0c;以包含支持ADS的模板&am…