鸿蒙NEXT开发浅进阶到精通02:APP隐私弹窗和启动页自定义创建
写在前面
在APP开发中呈现给用户的第一页面就是隐私政策和用户协议弹窗(后文简称隐私弹框)了,用老实话来讲,一个APP和用户没有什么法律纠纷就没有,有用到时,这两个文件就起到大的用途。 再白话一点讲,没这个弹框,上架审核不会通过的。而开发一个鸿蒙Next APP的隐私弹窗呢,本文将会从产品业务逻辑层面和代码层面逐一叙述,看完和CV本文代码,可满足绝大多少APP的场景需要,当然演示项目,UI还需自行优化。这里有个好消息就是鸿蒙元服务的这一块弹框是不需要开发的,官方只需要你在AGC平台上填入对应的链接即可。
概念概述
隐私弹框与APP内的其他常见弹框,如拨打电话弹框-删除提示弹框的场景,但是在产品和出现逻辑上有本质区别,隐私弹框讲究的是,用户首次下载弹出,不点击同意,就退出APP,点击同意后进入APP,再次打开除非重新下载安装不会再弹出。而且重要一点要防止用户什么也不点击,使用屏幕侧滑返回,来去掉弹框直接使用APP。
实战流程和过程注解
在上文我们提到隐私弹框和其他弹框的本质区别:
- 用户首次下载弹出
- 不点击同意或者点击不同意/取消等,就退出APP
- 点击同意后进入APP,以后再进入APP不会弹出
- 放在屏幕侧滑,让弹框消失,用户越过隐私弹框使用APP
那么我们也逐一展开,首先看下实际中一些朋友遇到的问题和想法 小白:这个弹窗干啥用的?
大白答:为了各种要求规定吧,反正你不点同意,这个APP主页用户股东是进不去了,那这个同意一次就OK了,卸载之前或者注销和切换账号前就不用弹出。
那么既然后一次性必点属性,肯定要设置一个全局持久变量是最基本的(如果有账号相关就住这之前去请求后端的这个字段)
小白:那这个弹框在哪出现嘞,有尝试过在主页面index中的aboutTo里弹出,好像也行哦!
大白答:行是行,但根据路由的尿性,用户点击返回,或者侧滑返回,也能进入页面,这时候就审核不过,因为用户并没有同意你的隐私协议,就会存在争议和风险。
所以启动页就特么诞生了,又能做广告宣传海报,又能防止用户无门槛进入APP/元服务
水了这么多,上代码(这里以简单的无后端账号信息 的demo举例个栗子)
一、设置启动页
在EntryAbility中,进入pages/inex之前,创建一个Windows展示
// 创建一个子窗口 子窗口加载广告 广告播完 窗口销毁
let isFirstOpen = AppStorage.get('isFirstOpen') as boolean
if (!isFirstOpen) {
const win = await windowStage.createSubWindow('ad_window')
await win.showWindow()
win.setUIContent('pages/Start')
}
这里有个布尔值,就是持久化来的,判断要不要创建这个启动页,在客户要求有启动页的时候,可以设置在页面内部控制这个变量,是否再弹出弹框,这里Demo直接控制是否有启动页(v的时候要注意哦) 至于为什么设置启动页,上文提到是一举两得,还有一个层面是笔者不设置启动页时,对于用户侧滑屏幕操作越过这个弹框,不好控制。有不设置启动页,也能防止用户越过弹框也还请评论区交流
二、页面有了,创建弹窗,在这个里面用那个持久布尔值isFirstOpen来做判断,可以用首选项也可以本地持久化
启动页代码
import { window } from '@kit.ArkUI'
import { agreementPolicyDialog } from '../components/agreementPolicyDialog'
import common from '@ohos.app.ability.common'
PersistentStorage.persistProp('isFirstOpen', false)
const context = getContext(this) as common.UIAbilityContext
@Entry
@Component
struct Start {
@StorageLink('isFirstOpen') isFirstOpen: boolean = false
async onPageShow() {
if (this.isFirstOpen) {
this.closeWin()
} else {
this.controller.open()
}
}
controller: CustomDialogController = new CustomDialogController({
builder: agreementPolicyDialog(), customStyle: true, cancel: () => {
context.terminateSelf()
}
})
onBackPress(): boolean | void {
if (!this.isFirstOpen) {
context.terminateSelf()
// this.controller.close()
}
return true
}
//关闭广告
closeWin() {
window.findWindow('ad_window').destroyWindow()
}
build() {
Stack({ alignContent: Alignment.TopEnd }) {
}.height('100%').width('100%').backgroundColor(Color.White)
}
}
这里代码就是启动页页面,弹框也在这里弹出,有意思的是我们设置启动页背景为纯白色,在不添加企业海报广告或者logo时,弹出弹框的UI效果跟元服务类似。
创建弹框结构就截图吧,这里注意要给到点击的字段隐私政策和协议的标题,使用text内部套span即可设置隐私和协议的颜色与点击事件
在设置弹框的时候,要注意cancel函数 的调用,放在返回事件中调用一次,防止用户返回,返回也执行这个取消函数内的退出APP代码
三、意外并重要的知识点--无损退出APP 的代码
这行代码要注意,收到那个导入window方法和创建实例再在页面中调用,一是在取消按钮下,一是在onBackPress这个生命函数中使用,因为用户看到弹窗,不惦记取消和确定,直接返回也是一种“不同意”,也是要退出APP的,这段代码及其珍贵,看到这里一定要给个赞哦,,
四、注意一次性布尔值的判断逻辑
那他同意了,就好办了,设置为true,销毁这个启动页,就自动进入主页面了,如果保留海报页仅控制这个弹窗的出现次数,就住EntryAbility中取消判断页面的创建,这里做一个定时器销毁启动页即可,这里不过多赘述
那不同意,也好办,你甚至不用设置false,直接关闭弹窗并退出APP了
因为你在初始化这个持久变量时,就设置了false(这里也展示了如何注册持久化变量,这个要放在整个应用启动前,在老版鸿蒙编辑器中,mac版是可以放在entryability中的,现在应该是不让了,有兴趣的朋友可以试试)