AR 眼镜之-开关机定制-实现方案

news2024/9/23 9:33:15

目录

📂 前言

AR 眼镜系统版本

开关机定制

1. 🔱 技术方案

1.1 技术方案概述

1.2 实现方案

1)开机 Logo

2)开机音效

3)开机动画

4)关机动画

5)关机弹窗

2. 💠 开机 Logo

2.1 使用原厂烧机工具验证

2.2 定制开机 Logo 文件

3. ⚛️ 关机弹窗

3.1 长按电源键关机时序图

3.2 关机弹窗 UI 定制

步骤一:在 ./frameworks/base/core/res/res/values/config.xml 文件中增删弹窗内选项

步骤二:在 ./frameworks/base/core/res/res/layout/global_actions_item.xml 文件调整界面 UI;

步骤三:为关机/重启使用的 SinglePressAction 增加 Hover 前后的图片替换逻辑;

3.3 定制点击关机/重启后的功能逻辑

步骤一:在 ShutdownThread 文件的 shutdownInner 方法中定制关机逻辑

步骤二:在 ShutdownThread 文件的 beginShutdownSequence 方法中定制关机过程的 UI(AggShutdownDialog)

4. ✅ 小结


📂 前言

AR 眼镜系统版本

        W517 Android9。

开关机定制

        开关机定制主要包括:开机 Logo、开机音效、开机动画、关机动画、关机弹窗,下面我们主要针对如上五部分进行定制。

1. 🔱 技术方案

1.1 技术方案概述

        开机 Logo 主要是 Logo 文件替换;对于开机音效、开机动画以及关机动画,主要是将相应文件内置到对应位置即可;而对于关机弹窗,是需要定制长按电源键的关机弹窗流程和UI修改的,会相对复杂一些。

1.2 实现方案

  1. 先使用原厂烧机工具验证,在如下目录替换 Logo 文件和 fastboot 文件后烧机验证是否生效:ResearchDownload_R25.21.1401\Bin\ImageFiles\_DownloadFiles2EC4_1153FD4_0\;

  2. 将 Logo 文件放置到如下位置:vendor\sprd\release\IDH\uws6151_1h10_gofu-userdebug-native\W517_1h10_GOFU\unisoc_HWVGA_480_640.bmp 以及 vendor\sprd\release\IDH\uws6151_1h10_gofu-user-native\W517_1h10_GOFU\unisoc_HWVGA_480_640.bmp;

  3. 将 fastboot 使用的 Logo 文件放置到如下位置:vendor\sprd\release\IDH\uws6151_1h10_gofu-userdebug-native\W517_1h10_GOFU\unisoc_HWVGA_480_640.bmp(1) 以及 vendor\sprd\release\IDH\uws6151_1h10_gofu-user-native\W517_1h10_GOFU\unisoc_HWVGA_480_640.bmp(1)。

2)开机音效
  1. 内置 bootsound.mp3,将 bootsound.mp3 文件放在如下路径:device\sprd\sharkl5\uws6151_1h10_go\;

  2. 配置烧机时将文件内置到整机,在 device\sprd\sharkl5\uws6151_1h10_go\uws6151_1h10_gofu.mk 文件中增加如下内容:PRODUCT_COPY_FILES += $(BOARDDIR)/bootsound.mp3:system/media/bootsound.mp3。

        由于此部分相对简单,所以后文不再单独章节介绍。

3)开机动画
  1. 制作 bootanimation.zip,本人在此文章有详细介绍,这里就不再赘述了:Android 自定义开机动画_rk3568更换开机动画-CSDN博客

  2. 内置 bootanimation.zip,将 bootanimation.zip 文件放在如下路径:device\sprd\sharkl5\uws6151_1h10_go\;

  3. 配置烧机时将文件内置到整机,在 device\sprd\sharkl5\uws6151_1h10_go\uws6151_1h10_gofu.mk 文件中增加如下内容:PRODUCT_COPY_FILES += $(BOARDDIR)/bootanimation.zip:system/media/bootanimation.zip。

        由于此部分相对简单,所以后文不再单独章节介绍。

4)关机动画

        与开机动画的制作与定制基本完全一样,将 bootanimation.zip 改为 shutdownanimation.zip 即可。

  1. 制作 shutdownanimation.zip,本人在此文章有详细介绍,这里就不再赘述了:Android 自定义开机动画_rk3568更换开机动画-CSDN博客

  2. 内置 shutdownanimation.zip,将 shutdownanimation.zip 文件放在如下路径:device\sprd\sharkl5\uws6151_1h10_go\;

  3. 配置烧机时将文件内置到整机,在 device\sprd\sharkl5\uws6151_1h10_go\uws6151_1h10_gofu.mk 文件中增加如下内容:PRODUCT_COPY_FILES += $(BOARDDIR)/bootanimation.zip:system/media/shutdownanimation.zip。

        由于此部分相对简单,所以后文不再单独章节介绍。

5)关机弹窗
  1. 梳理长按电源键关机弹窗逻辑,从 PhoneWindowMananger 按键响应 power 键长按事件到 SystemUI 弹出关机界面 dialog 的流程。Android 原生的关机界面有两种,一种是 LegacyGlobalActions 中的 dialog,另一种是 SystemUI 中的 GlobalActionsDialog,常规情况下默认是弹出 SystemUI 中的关机界面,当 SystemUI 没有正常工作时才会弹出 LegacyGlobalActions 中的关机界面,本文我们分析正常情况 SystemUI 弹出的 GlobalActionsDialog;

  2. 关机弹窗 UI 定制,可在 ./frameworks/base/core/res/res/values/config.xml 文件中增删弹窗内选项,也可在 ./frameworks/base/core/res/res/layout/global_actions_item.xml 文件中调整界面 UI 等;

  3. 定制点击关机/重启后的功能逻辑,关机/重启时可显示厂商的定制化 UI。

2.1 使用原厂烧机工具验证

        替换 unisoc_HWVGA_480_640.bmp Logo 文件以及 unisoc_HWVGA_480_640.bmp(1) fastboot 文件烧机验证是否生效。

2.2 定制开机 Logo 文件

替换 Logo 文件和 fastboot 文件。

3. ⚛️ 关机弹窗

3.1 长按电源键关机时序图

3.2 关机弹窗 UI 定制

步骤一:在 ./frameworks/base/core/res/res/values/config.xml 文件中增删弹窗内选项
    <string-array translatable="false" name="config_globalActionsList">
        <item>power</item>
        <item>restart</item>
<!--        // Agg patch-->
<!--        // Add by agg 2024-03-07-->
<!--        <item>lockdown</item>-->
<!--        <item>logout</item>-->
<!--        <item>bugreport</item>-->
<!--        <item>screenshot</item>-->
<!--        // Agg patch end-->
    </string-array>

        只保留关机和重启选项。

步骤二:在 ./frameworks/base/core/res/res/layout/global_actions_item.xml 文件调整界面 UI;

步骤三:为关机/重启使用的 SinglePressAction 增加 Hover 前后的图片替换逻辑;

./frameworks/base/core/java/com/android/internal/globalactions/SinglePressAction.java:

v.setOnHoverListener((view, event) -> {
  if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
      view.setBackgroundResource(R.drawable.ic_power_off_restart_bg_foc);
      AnimationUtils.getInstance().selectItemAnimator(view);
  } else if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
      AnimationUtils.getInstance().unSelectItemAnimator(view);
      view.setBackgroundResource(R.drawable.ic_power_off_restart_bg_nor);
  }
  return false;
});

3.3 定制点击关机/重启后的功能逻辑

        用户点击关机时序图如下:

步骤一:在 ShutdownThread 文件的 shutdownInner 方法中定制关机逻辑
    private static void shutdownInner(final Context context, boolean confirm) {
        // ShutdownThread is called from many places, so best to verify here that the context passed
        // in is themed.
        context.assertRuntimeOverlayThemable();

        // ensure that only one thread is trying to power down.
        // any additional calls are just returned
        synchronized (sIsStartedGuard) {
            if (sIsStarted) {
                Log.d(TAG, "Request to shutdown already running, returning.");
                return;
            }
        }

        final int longPressBehavior = context.getResources().getInteger(
                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
        final int resourceId = mRebootSafeMode
                ? com.android.internal.R.string.reboot_safemode_confirm
                /*UNISOC bug 908624,add confirm dialog.*/
                : (mReboot
                ? com.android.internal.R.string.reboot_device_confirm
                /*UNISOC bug 908624,add confirm dialog.*/
                : (longPressBehavior == 2
                        ? com.android.internal.R.string.shutdown_confirm_question
                        : com.android.internal.R.string.shutdown_confirm));

        Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);

        // Agg patch
        // Add by agg 2024-05-22
        beginShutdownSequence(context);
        // Agg patch end
//        if (confirm) {
//            final CloseDialogReceiver closer = new CloseDialogReceiver(context);
//            if (sConfirmDialog != null) {
//                sConfirmDialog.dismiss();
//            }
//            sConfirmDialog = new AlertDialog.Builder(context)
//                    .setTitle(mRebootSafeMode
//                            ? com.android.internal.R.string.reboot_safemode_title
//                            /*UNISOC bug 908624*/
//                            :(mReboot
//                            ? com.android.internal.R.string.reboot_device_title
//                            /*UNISOC bug 908624*/
//                            : com.android.internal.R.string.power_off))
//                    .setMessage(resourceId)
//                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
//                        public void onClick(DialogInterface dialog, int which) {
//                            beginShutdownSequence(context);
//                        }
//                    })
//                    .setNegativeButton(com.android.internal.R.string.no, null)
//                    .create();
//            closer.dialog = sConfirmDialog;
//            sConfirmDialog.setOnDismissListener(closer);
//            sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
//            sConfirmDialog.show();
//        } else {
//            beginShutdownSequence(context);
//        }
    }
步骤二:在 ShutdownThread 文件的 beginShutdownSequence 方法中定制关机过程的 UI(AggShutdownDialog)
    private static void beginShutdownSequence(Context context) {
        synchronized (sIsStartedGuard) {
            if (sIsStarted) {
                Log.d(TAG, "Shutdown sequence already running, returning.");
                return;
            }
            sIsStarted = true;
        }

        // SPRD:add for shutdownanim
        if (shutdownAnim.hasShutdownAnimation() &&
                !(mReason != null && mReason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE))) {
            shutdownAnim.playShutdownAnimation();
        } else {
            // MetaBounds patch
            // Add by tianbinbin 2024-07-30
//            sInstance.mProgressDialog = showShutdownDialog(context);
            MBShutdownDialog shutdownDialog = new MBShutdownDialog(context);
            shutdownDialog.show();
            if (mReboot) {
                shutdownDialog.setMessage(context.getText(com.android.internal.R.string.reboot_to_reset_message));
            } else {
                shutdownDialog.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
            }
            // MetaBounds patch end
        }

4. ✅ 小结

        对于开关机定制,本文只是一个基础实现方案,更多业务细节请参考产品逻辑去实现。

        另外,由于本人能力有限,如有错误,敬请批评指正,谢谢。


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

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

相关文章

C++笔试题汇总

C笔试题汇总记录 一、概述二、概念分类1. 结构体1. C 和 C 中 struct 有什么区别&#xff1f;2. C中的 struct 和 class 有什么区别&#xff1f; 2. 类相关1. 类的大小1. 空类的大小2. 一般非空类大小3. 有虚函数类4. 有虚函数类的继承5. 只有虚函数6. 静态数据成员 2. C的三大…

【分享】格力手机色界G0245D 刷REC、root、 救砖、第三方rom教程和资源

开门见山 帮别人弄了一台 格力G0245D&#xff0c;把找到的资源和教程分享一下 教程 这个写的很详细了格力手机色界G0245D-Root-最简指南 不过教程里刷rec这一步漏了加上电源键&#xff0c;加上就行了。 附加参考&#xff1a;格力手机2刷机 格力手机二代刷机 GREE G0215D刷机…

C++ 特殊类设计以及单例模式

目录 1 不能被拷贝 2 只能在堆上创建对象 3 只能在栈上创建对象 4 禁止在堆上创建对象 5 不能被继承的类 6 单例类 特殊类就是一些有特殊需求的类。 1 不能被拷贝 要设计一个防拷贝的类&#xff0c;C98之前我们只需要将拷贝构造以及拷贝赋值设为私有&#xff0c;同时只声明…

在HFSS中对曲线等结构进行分割(Split)

在HFSS中对曲线进行分割 我们往往需要把DXF等其他类型文件导入HFSS进行分析&#xff0c;但是有时需要对某一个曲线单独进行分割成两段修改。 如果是使用HFSS绘制的曲线&#xff0c;我们修改起来非常方便&#xff0c;修改参数即可。但是如果是导入的曲线&#xff0c;则需要使用…

代码随想录训练营 Day31打卡 贪心算法 part05 56. 合并区间 738. 单调递增的数字 968. 监控二叉树

代码随想录训练营 Day31打卡 贪心算法 part05 一、 力扣56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中…

【JavaEE】JVM 内存区域划分,以及 Java 垃圾回收机制引用计数器,可达性分析等

目录 1. JVM执行流程 2. JVM运行时数据区 2.1 堆 2.2 Java虚拟机栈(线程私有) 2.3本地方法栈(线程私有) 2.4 程序计数器 2.5 元数据区 3. JVM的类加载机制 1) 加载 2) 验证 3) 准备 4) 解析 5) 初始化 双亲委派模型 4. java垃圾回收 4.1 死亡对象判断方法 a) …

超精细CG杰作:8K壁纸级官方艺术插画,展现极致美丽与细节的汉服女孩

极致精美的数字艺术杰作&#xff1a;8K壁纸级别的官方插画&#xff0c;展现超高清细节与和谐统一的美感&#xff0c;女孩的精致面容与眼神在光影下熠熠生辉&#xff0c;汉服主题下的超高分辨率作品&#xff0c;文件巨大&#xff0c;细节丰富&#xff0c;令人惊叹。 正向提示词…

内存泄漏之如何使用Visual Studio的调试工具跟踪内存泄漏?

使用Visual Studio的调试工具跟踪内存泄漏是一个系统性的过程&#xff0c;主要包括启用内存泄漏检测、运行程序、分析内存使用情况以及定位泄漏源等步骤。 Visual Studio提供了多种方式来检测内存泄漏&#xff0c;你可以根据自己的需求选择合适的方法。 注意&#xff1a;下面…

父页面选项式api,子页面组合式api,子页面如何获取父页面的方法以及传值到将子页面的值传给父页面

开发的项目中是vue3的项目&#xff0c;但是有些同事用vue2中的选项式api写法&#xff0c;有些同事使用的是vue3组合式api的写法&#xff0c;此时子页面需要获取父页面的方法把数据传入父页面的方法中 父页面&#xff1a; 在父页面中order-item组件中创建自定义方法navigation和…

Leetcode每日刷题之剑指offer 57.和为s的两个数字(C++)

1.题目解析 现在题目改名为LCR.查找总价值为目标值的两个商品&#xff0c;虽然题目改变但是核心并未变化&#xff0c;都是需要寻找出和为指定数字的两数 2.算法原理 我们由题目知道给出的数组是递增的&#xff0c;所以在数组的首尾固定两个指针&#xff0c;判断其和是否为指定数…

Ceph篇之利用shell脚本实现批量创建bucket桶

Ceph创建bucket桶 在 Ceph 中创建桶&#xff08;bucket&#xff09;需要使用 Ceph 对象网关&#xff08;RGW&#xff09;。 注&#xff1a;如果查看shell批量创建脚本请直接参见目录3 1. 利用radosgw-admin工具创建桶 确保 Ceph 集群和对象网关已正确配置 确保你的 Ceph 集群…

快速了解Vi 和 Vim 编辑器三种模式及快捷键使用

&#x1f600;前言 本篇博文是关于Vi 和 Vim 编辑器的三种模式及快捷键使用&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意…

大数据产业链图谱_产业链全景图_大数据行业市场分析

数据作为新型生产要素&#xff0c;是数字化、网络化、智能化的基础&#xff0c;已快速融入生产、分配、流通、消费和社会服务管理等各环节&#xff0c;影响着千行百业&#xff0c;推动着我国数字经济的蓬勃发展。 大数据又称巨量数据、海量数据&#xff0c;是由数量巨大、结构…

C语言 | Leetcode C语言题解之第341题扁平化嵌套列表迭代器

题目&#xff1a; 题解&#xff1a; struct NestedIterator {int *vals;int size;int cur; };void dfs(struct NestedIterator *iter, struct NestedInteger **nestedList, int nestedListSize) {for (int i 0; i < nestedListSize; i) {if (NestedIntegerIsInteger(neste…

Sprache:轻量级C#解析器构建,可用于字符串验证等。

我们在开发中&#xff0c;经常需要对一些结构化文本进行解析&#xff0c;用于验证是否符合规则。我们一般会使用正则表达式&#xff0c;同时正则表达式也非常强大&#xff0c;但正则表达式在语法不便阅读与维护。 下面介绍一个简单、轻量级的库&#xff0c;方便我们在C#代码中…

React 学习——打包后,包体积可视化

1、安装插件 &#xff08; source-map-explorer &#xff09; npm i source-map-explorer 2、在配置文件package.json中加入 &#xff08; "analyze": "source-map-explorer build/static/js/*.js" &#xff09;&#xff0c;位置截图 "analyze&q…

Flask 线上高并发部署方案实现

目录 1、Flask默认多线程执行 2、使用gevent.pywsgi实现 3、是用uWSGI服务器实现 1、Flask默认多线程执行 前言&#xff1a;在Flask的较早版本中&#xff0c;默认并不支持多线程模式。然而&#xff0c;从Flask 0.9版本开始&#xff0c;引入了多线程模式的支持&#xff0c;并…

红酒与旅游攻略:旅行途中的风味之选

在旅行的道路上&#xff0c;我们总是渴望寻找那些能够触动心灵、留下深刻记忆的不同体验。而红酒&#xff0c;作为一种充满韵味和故事的饮品&#xff0c;无疑是旅行途中的风味之选。洒派红酒&#xff08;Bold & Generous&#xff09;&#xff0c;这款定制红酒&#xff0c;以…

基于xilinx IP的频域脉冲压缩算法的实现和matlab仿真

工具&#xff1a;matlabR2021b&#xff0c;vivado2018.3. 脉冲压缩的原理 脉冲压缩实际上就是对接收信号进行匹配滤波处理。根据发射的波形不同&#xff0c;脉冲压缩时选择不同的匹配滤波器系数。 数字脉冲压缩的实现方式有两种: 一是时域卷积法; 二是频域乘积法。依据傅里叶…

智能化包括自动化与非自动化

智能化通常指的是系统或设备具备智能功能&#xff0c;以提高其自主性和效率。智能化可以分为自动化与非自动化两大类&#xff0c;每一类都有其独特的特点和应用场景。 一、自动化 自动化指的是系统能够在无需人为干预的情况下完成任务或操作。自动化系统通常依赖于预设的规则、…