【关键字】
隐私、弹窗、元服务、协议
【介绍】
每个元服务必须提供隐私声明,否则将导致提交元服务发布上架时,审核无法通过。隐私声明的具体要求请参见隐私声明规范。用户使用元服务前,必须引导其了解隐私声明信息,获取用户授权后,才能继续使用元服务。
废话不多说,上代码!!
【方式一】推荐在首次启动或者注册登录时呈现隐私声明:
代码结构:新建detailman页面用来显示上图超链接跳转的H5页面,index页面是元服务首页
实现代码:index.hml文件,使用dialog组件实现协议弹出框,协议内容使用<text>+<span>组件实现协议跳转,span的value定义在JS文件的data中。(这里请注意:直接将协议内容写到组件内无法实现首行缩进,API7+才支持)
<div class="container"><button style="height: 5%; width: 30%;" onclick="onShow">Helloworld</button><!--方式一:首次打开弹窗-->
<!--下方dialog组件整体复制到元服务首页hml中任意位置-->
<!-- copy start--><dialog id="dragDialog" dragable="false" style="height: 60%; width: 90%; margin-bottom: 15%;"><div style="flex-direction: column; align-items: center; height: 100%; width: 100%;"><div style="height: 15%; width: 100%; justify-content: center; align-items: center;"><text style="font-size: 20px; font-weight: 900;">{{ this.head }}</text></div><div style="height: 70%; width: 100%; justify-content: center;"><text style="width: 95%; text-align: start; padding: 2%; line-height: 25px;"><span class="fontStyle">{{ firstContext }}</span><span class="fontStyle" style="color: #ff0800ff;" onclick="go(rule)">{{ rule }}</span><span class="fontStyle">,</span><span class="fontStyle" style="color: #ff0800ff;" onclick="go(privacy)">{{ privacy }}</span><span class="fontStyle">{{ secondContext }}</span></text></div><div style="height: 15%; width: 100%; flex-direction: row; justify-content: center; align-items: center;"><button type="text" style="width: 40%; font-size: 20px; text-align: center; text-color: black;"onclick="noAgree">不同意</button><button type="text" style="width: 40%; font-size: 20px; text-align: center; text-color: #ff0800ff;"onclick="agree">同意</button></div></div></dialog>
<!-- copy end-->
</div>
index.js文件,在oninit中获取轻量存储文件路径,在onshow中判断是否已同意协议,未同意则弹窗。用户同意则保存同意数据到轻量存储中(要实现用户关联建议使用云存储)
import Router from '@system.router';
import storage from '@ohos.data.storage';
import featureAbility from '@ohos.ability.featureAbility';
export default {data: {head: "用户隐私条款",privacy: "《隐私政策》",rule: "《用户协议》",firstContext: " 为了更好地保护您的个人信息,我们根据最新的法律法规及相关政策的要求,对隐私条款进行了更新,请您仔细阅读并确认",secondContext: "。(特别是加粗及下划线部分),我们会严格按照本协议的约定收集、使用、存储您在" +"使用本软件过程中设计的个人信息,以便为您提供更优质的服务,感谢您的信任与理解。\n 如需换行参照此样例实现,如不需要请删除。。。",filepath: "",imagePath:"/common/images/uncheck.png"},onInit() {var context = featureAbility.getContext();context.getFilesDir().then((filePath) => {this.filepath = filePath + '/myDatastore';})},onShow() {let dataStorage = storage.getStorageSync(this.filepath);//方式一:判断页面打开是否需要弹窗dataStorage.get("hasAgree", "false").then((value) => {if (value == "false") {this.$element('dragDialog').show();}})},agree() {//处理同意的业务this.$element('dragDialog').close();let dataStorage = storage.getStorageSync(this.filepath);dataStorage.putSync("hasAgree", "true");dataStorage.flushSync();},noAgree() {//处理不同意的业务this.$element('dragDialog').close();//允许继续浏览,或选择退出},go(flag) {let url = "https://www.51miz.com/so-wendang/11963302.html?utm_term=12452681&utm_source=baidu3&bd_vid=8250967139616741558"if (flag == "《用户协议》") {url = "https://www.51miz.com/so-wendang/11963302.html?utm_term=12452681&utm_source=baidu3&bd_vid=8250967139616741558"}else {url = "https://www.tukuppt.com/wordmuban/yinsizhengce.html?plan=11177-37593-12085827&bd_vid=8439929694061694080"}Router.push({uri: "pages/detailman/detailman", params: {param: url}})this.$element('dragDialog').close();},
}
index.css文件:
.container {display: flex;flex-direction: column;justify-content: flex-start;align-items: center;left: 0px;top: 0px;width: 100%;height: 100%;
}
.fontStyle{font-size: 16px
}
协议详情页面detailman.hml,使用web组件显示H5内容,web组件会覆盖页面其他组件,无法使用组件事件实现回退,如果需要回退可以考虑使用JAVA webView实现
<div class="container"><web src="{{param}}"></web>
</div>
detailman.js,定义param变量接受index页面router传过来的参数
export default {data: {param: ""},onInit() {}
}
detailman.css
.container {display: flex;flex-direction: column;justify-content: center;align-items: center;left: 0px;top: 0px;width: 100%;height: 100%;}
【效果展示】
【参考样式二】如果元服务需要登录后使用,建议登录界面提供隐私声明提示,引导用户阅读和授权,获取授权后才可继续使用。
代码结构:新建detailman页面用来显示上图超链接跳转的H5页面,index页面是元服务首页,common下新增
实现代码:index.hml文件,因JS UI中不支持checkBox组件,这里使用image来实现选择效果
<div class="container">
<!--方式二:首页使用check框--><div style="flex-direction: row; align-items: center; justify-content: center;"><image id="checkImage" style="width: 25px; height: 25px;margin: 3%;" src="{{imagePath}}"onclick="agreeCheck"></image><text style="width: 80%; text-align: start; padding: 2%; line-height: 25px;justify-content: center;"><span class="fontStyle" style="color: #ff181717;">我已阅读并同意</span><span class="fontStyle" style="color: #ff0800ff;" onclick="go(rule)">{{ rule }}</span><span class="fontStyle">与</span><span class="fontStyle" style="color: #ff0800ff;" onclick="go(privacy)">{{ privacy }}</span></text></div>
</div>
index.js文件,在oninit中获取轻量存储文件路径,在onshow中查询存储数据,初始化check状态。
import Router from '@system.router';
import storage from '@ohos.data.storage';
import featureAbility from '@ohos.ability.featureAbility';
export default {data: {privacy: "《隐私政策》",rule: "《用户协议》", filepath: "",imagePath:"/common/images/uncheck.png"},onInit() {var context = featureAbility.getContext();context.getFilesDir().then((filePath) => {this.filepath = filePath + '/myDatastore';})},onShow() {let dataStorage = storage.getStorageSync(this.filepath);//方式二:打开页面时初始化用户是否已同意dataStorage.get("hasAgree", "false").then((value) => {if (value == "false") {this.imagePath = "/common/images/uncheck.png"}else{this.imagePath = "/common/images/check.png"}})},go(flag) {let url = "https://www.51miz.com/so-wendang/11963302.html?utm_term=12452681&utm_source=baidu3&bd_vid=8250967139616741558"if (flag == "《用户协议》") {url = "https://www.51miz.com/so-wendang/11963302.html?utm_term=12452681&utm_source=baidu3&bd_vid=8250967139616741558"}else {url = "https://www.tukuppt.com/wordmuban/yinsizhengce.html?plan=11177-37593-12085827&bd_vid=8439929694061694080"}Router.push({uri: "pages/detailman/detailman", params: {param: url}}) },agreeCheck(){let dataStorage = storage.getStorageSync(this.filepath);dataStorage.get("hasAgree", "false").then((value) => {if (value == "false") {//处理同意逻辑并保存已同意参数dataStorage.putSync("hasAgree", "true");dataStorage.flushSync();this.imagePath = "/common/images/check.png"}else {//处理不同意逻辑并保存已同意参数dataStorage.putSync("hasAgree", "false");dataStorage.flushSync();this.imagePath = "/common/images/uncheck.png"}})}}
index.css文件:
.container {display: flex;flex-direction: column;justify-content: flex-start;align-items: center;left: 0px;top: 0px;width: 100%;height: 100%;
}
.fontStyle{font-size: 16px
}
协议详情页面detailman.hml,参照方式一实现
【效果展示】