鸿蒙隐私弹窗功能开发实践

2025-06-04 12:58:10
106次阅读
0个评论

鸿蒙隐私弹窗功能开发实践

最近在开发鸿蒙应用时,发现隐私弹窗是一个绕不开的功能。它不仅关系到用户体验,更关系到应用的合规性。经过一番摸索和实践,终于实现了一个还算满意的隐私弹窗,这里分享下开发心得。

一、开发背景

在开发鸿蒙应用时,隐私弹窗是一个非常重要的功能。它不仅关系到用户体验,更关系到应用的合规性。本文将详细介绍如何在鸿蒙应用中实现一个美观、实用的自定义隐私弹窗。

二、实现步骤

2.1 创建隐私弹窗组件

首先创建一个自定义的隐私弹窗组件 PrivacyDialog.ets:

@CustomDialog
export struct PrivacyDialog {
  controller: CustomDialogController;
  context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  confirm: () => void = () => {};
  cancel: () => void = () => {};

  build() {
    Column() {
      // 标题
      Text('隐私政策')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 16, bottom: 16 })
        .textAlign(TextAlign.Center)
        .fontColor($r('app.color.text_primary'))

      // 内容
      Text() {
        Span('本应用重视并保护所有用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照隐私政策')
          .fontSize(16)
          .fontColor($r('app.color.text_secondary'))

        Span('的规定使用和披露您的个人信息。可阅读')
          .fontSize(16)
          .fontColor($r('app.color.text_secondary'))
          
        Span('服务协议')
          .fontSize(16)
          .fontColor($r('app.color.brand_color'))
          .onClick(() => {
            this.controller.close();
            router.pushUrl({
              url: 'pages/UserAgreementDetail',
              params: { needShowDialog: true }
            });
          })
          
        Span('和')
          .fontSize(16)
          .fontColor($r('app.color.text_secondary'))
          
        Span('隐私政策')
          .fontSize(16)
          .fontColor($r('app.color.brand_color'))
          .onClick(() => {
            this.controller.close();
            router.pushUrl({
              url: 'pages/PrivacyPolicyDetail',
              params: { needShowDialog: true }
            });
          })
      }
      .margin({ left: 16, right: 16 })
      .textAlign(TextAlign.Center)

      // 按钮
      Row() {
        Button('同意')
          .width('45%')
          .height(40)
          .backgroundColor($r('app.color.brand_color'))
          .fontColor(Color.White)
          .onClick(() => {
            this.confirm();
            this.controller.close();
          })

        Button('不同意并退出')
          .width('45%')
          .height(40)
          .fontColor($r('app.color.text_secondary'))
          .backgroundColor($r('app.color.card_background'))
          .onClick(() => {
            this.cancel();
            this.controller.close();
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ top: 40, bottom: 16 })
    }
    .width('90%')
    .backgroundColor($r('app.color.card_background'))
    .borderRadius(16)
    .padding(16)
  }
}

2.2 在欢迎页面中使用

在欢迎页面 Welcome.ets 中集成隐私弹窗:

@Entry
@Component
struct Welcome {
  @State showPrivacyDialog: boolean = false;
  private context = getContext(this) as common.UIAbilityContext;
  private preferences: dataPreferences.Preferences | null = null;
  
  private dialogController: CustomDialogController = new CustomDialogController({
    builder: PrivacyDialog({
      context: this.context,
      confirm: async () => {
        try {
          if (this.preferences) {
            await this.preferences.put('privacy_agreed', true);
            await this.preferences.flush();
          }
          router.replaceUrl({ url: 'pages/Index' });
        } catch (error) {
          console.error('Update privacy agreement flag failed:', error);
        }
      },
      cancel: () => {
        this.context.terminateSelfWithResult({
          resultCode: 0,
          want: {}
        });
      }
    }),
    alignment: DialogAlignment.Center,
    offset: { dx: 0, dy: 0 },
    customStyle: true,
    autoCancel: false
  });

  async aboutToAppear() {
    try {
      this.preferences = await dataPreferences.getPreferences(this.context, 'app_settings');
      const hasAgreed = await this.preferences.get('privacy_agreed', false);
      
      if (!hasAgreed) {
        this.showPrivacyDialog = true;
        this.dialogController.open();
      } else {
        setTimeout(() => {
          router.replaceUrl({ url: 'pages/Index' });
        }, 1100);
      }
    } catch (error) {
      console.error('Initialize preferences failed:', error);
    }
  }
}

三、踩坑记录

3.1 界面设计

  • 一开始弹窗布局比较随意,后来参考了一些主流应用的设计,才改得比较美观
  • 隐私政策说明文字太长,用户根本不会看,后来精简了一下
  • 按钮样式一开始不够醒目,改了几次才满意
  • 深色模式适配花了不少时间

3.2 交互体验

  • 查看详细隐私政策时,一开始没有关闭弹窗,导致用户操作很混乱
  • 服务协议和隐私政策的跳转逻辑改了好几次
  • 同意后跳转的时机把握不好,后来加了延时
  • 不同意退出时,一开始没有给用户确认的机会

3.3 数据存储

  • Preferences存储一开始没做好异常处理,导致数据丢失
  • 重复显示弹窗的问题折腾了好久
  • 重置隐私设置的功能是后来加的,因为用户有需求

四、注意事项

  1. 权限管理
  • 存储权限一定要申请,不然数据存不了
  • 权限申请流程要友好,不能太生硬
  1. 用户体验
  • 弹窗内容要简单直接,别整太复杂
  • 操作指引要清晰,别让用户猜
  • 详细政策要容易找到,但别太显眼
  1. 合规性
  • 法律法规一定要遵守,别给自己找麻烦
  • 用户隐私要保护好,这是底线
  • 必要的说明信息要写清楚,别含糊

五、总结

这个隐私弹窗功能,前后改了好几版,踩了不少坑。不过功夫不负有心人,最后的效果还算满意。如果你也在做类似功能,希望这篇文章能帮到你。

六、参考资源

欢迎体验

这个隐私弹窗功能已经集成到鸿蒙开发者工具箱里了,欢迎下载体验!

鸿蒙开发者工具箱


作者:在人间耕耘 邮箱:1743914721@qq.com 版权声明:本文为CSDN博主原创文章,转载请附上原文出处链接及本声明。

收藏00

登录 后评论。没有帐号? 注册 一个。