当前位置: 首页 > news >正文

AR 眼镜之-充电动画定制-实现方案

目录

📂 前言

AR 眼镜系统版本

充电动画

1. 🔱 技术方案

1.1 方案介绍

1.2 实现方案

关机充电动画

亮屏/锁屏充电动画

2. 💠 关机充电动画

2.1 关机充电动画核心处理类与路径

2.2 实现细节

步骤一:1)定制 ui.c 文件,适配分辨率

步骤一:2)定制 ui.c 文件,定制动画 UI

步骤二:新增定制的动画 UI 相关png图片

3. ⚛️ 亮屏/锁屏充电动画

3.1 亮屏/锁屏充电动画时序图

3.2 实现细节

步骤一:注册广播 Action 监听充电接通/断开/充满电等状态

步骤二:开发充电接通/断开/充满电的系统弹窗,显示对应动画

4. ✅ 小结


📂 前言

AR 眼镜系统版本

        W517 Android9。

充电动画

        Android 充电动画分为:关机充电动画 与 亮屏/锁屏充电动画,而且据了解 Android 原生系统只提供了关机充电动画,并未提供亮屏/锁屏充电动画,所以对于关机情况下需要定制,亮屏/锁屏情况下需要增加。

1. 🔱 技术方案

1.1 方案介绍

        技术方案概述:对于关机充电动画,是通过 minui 开发的,主要定制 ui.c 文件以及 /images/*.png 图片;对于亮屏/锁屏充电动画,主要通过监听系统充电连接、断开和充满电的广播去实现。

1.2 实现方案

关机充电动画
  1. 定制 ui.c 文件,适配分辨率,定制动画 UI;

  2. 新增定制的动画 UI 相关png图片。

亮屏/锁屏充电动画
  1. 注册 ACTION_POWER_CONNECTED、ACTION_POWER_DISCONNECTED、ACTION_BATTERY_OKAY 等广播 Action 监听充电接通/断开/充满电等状态;

  2. 开发充电接通/断开/充满电的系统弹窗,显示对应动画。

2. 💠 关机充电动画

2.1 关机充电动画核心处理类与路径

  1. 关机充电动画 UI 处理类:w517\vendor\sprd\proprietories-source\charge\ui.c

  2. 关机充电动画图片存放路径:w517\vendor\sprd\proprietories-source\charge\images\

  3. AR 眼镜上的充电动画图片存放路径:/vendor/etc/res/images/

2.2 实现细节

步骤一:1)定制 ui.c 文件,适配分辨率

步骤一:2)定制 ui.c 文件,定制动画 UI

步骤二:新增定制的动画 UI 相关png图片

3. ⚛️ 亮屏/锁屏充电动画

3.1 亮屏/锁屏充电动画时序图

3.2 实现细节

步骤一:注册广播 Action 监听充电接通/断开/充满电等状态
class BatteryListener(context: Context) {private val TAG = BatteryListener::class.java.simpleNameprivate val mContext: Contextprivate val mReceiver: BatteryBroadcastReceiverprivate val mBatteryChargeWindow: BatteryChargeWindowinit {mContext = contextmReceiver = BatteryBroadcastReceiver()mBatteryChargeWindow = BatteryChargeWindow()}fun register() {Log.e(TAG, "register: ")val filter = IntentFilter()
//        filter.addAction(Intent.ACTION_BATTERY_CHANGED) // 电量发生改变filter.addAction(Intent.ACTION_BATTERY_LOW) // 电量低filter.addAction(Intent.ACTION_BATTERY_OKAY) // 电量充满filter.addAction(Intent.ACTION_POWER_CONNECTED) // 接通电源filter.addAction(Intent.ACTION_POWER_DISCONNECTED) // 拔出电源mContext.registerReceiver(mReceiver, filter)mBatteryChargeWindow.init(mContext)}fun unregister() {Log.e(TAG, "unregister: ")mContext.unregisterReceiver(mReceiver)}private inner class BatteryBroadcastReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {Log.e(TAG, "onReceive: ${intent.action}")when (intent.action) {
//                Intent.ACTION_BATTERY_CHANGED -> {
//
//                }Intent.ACTION_BATTERY_LOW -> {}Intent.ACTION_BATTERY_OKAY -> {mBatteryChargeWindow.finishCharge()}Intent.ACTION_POWER_CONNECTED -> {SoundPoolTools.play(context, SoundPoolTools.MUSIC, R.raw.notification_power_connected)mBatteryChargeWindow.startCharge()}Intent.ACTION_POWER_DISCONNECTED -> {}}}}}
步骤二:开发充电接通/断开/充满电的系统弹窗,显示对应动画
class BatteryChargeWindow {private lateinit var mContext: Contextprivate lateinit var mWindowManager: WindowManagerprivate lateinit var mBatteryChargeView: Viewprivate lateinit var mChargingAnimation: LottieAnimationViewprivate lateinit var mFinishedChargingAnimation: LottieAnimationViewprivate lateinit var mBattery: AGGTextViewprivate var mLayoutParams: WindowManager.LayoutParams? = nullprivate var mIsBarWindowAdded = falseprivate val mUiHandler = Handler(Looper.getMainLooper())fun init(context: Context) {mContext = context.applicationContextmWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManagerinitLayoutParams()initView()}fun startCharge() {initLayoutParams()addBarWindow()mChargingAnimation.visibility = View.VISIBLEmChargingAnimation.playAnimation()mBattery.text = getBatteryLevel()mUiHandler.postDelayed({mChargingAnimation.cancelAnimation()mChargingAnimation.visibility = View.GONEremoveBarWindow()}, BATTERY_CHARGE_TIME_OUT)}@SuppressLint("SetTextI18n")fun finishCharge() {initLayoutParams()addBarWindow()mFinishedChargingAnimation.visibility = View.VISIBLEmFinishedChargingAnimation.playAnimation()mBattery.text = "100%"mUiHandler.postDelayed({mFinishedChargingAnimation.cancelAnimation()mFinishedChargingAnimation.visibility = View.GONEremoveBarWindow()}, BATTERY_CHARGE_TIME_OUT)}private fun initLayoutParams() {mLayoutParams = WindowManager.LayoutParams().apply {type = WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANELval density = mContext.resources.displayMetrics.densitywidth = (640 * density).toInt()height = (640 * density).toInt()flags =WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITSformat = PixelFormat.RGBA_8888 // 去除默认时有的黑色背景,设置为全透明gravity = Gravity.CENTERtitle = Constants.AGG_SYSUI_BATTERY_CHARGEx = 0y = 0dofIndex = 1 //  默认为1。 为0,则表示窗口为0DOF模式;为1,则表示窗口为3DOF模式;为2,则表示窗口为6DOF模式。setTranslationZ(Constants.TRANSLATION_Z_150CM)setRotationXAroundOrigin(-XrEnvironment.getInstance().headPose.roll)setRotationYAroundOrigin(-XrEnvironment.getInstance().headPose.yaw)setRotationZAroundOrigin(-XrEnvironment.getInstance().headPose.pitch)}}private fun initView() {mBatteryChargeView =LayoutInflater.from(mContext).inflate(R.layout.battery_charge_layout, null, false)mChargingAnimation = mBatteryChargeView.findViewById(R.id.charging)mFinishedChargingAnimation = mBatteryChargeView.findViewById(R.id.finishedCharging)mBattery = mBatteryChargeView.findViewById(R.id.battery)}private fun addBarWindow() {mUiHandler.post {synchronized(this) {if (!mIsBarWindowAdded) {try {mWindowManager.addView(mBatteryChargeView, mLayoutParams)} catch (e: Exception) {e.printStackTrace()}mIsBarWindowAdded = true}}}}private fun removeBarWindow() {mUiHandler.post {synchronized(this) {if (mIsBarWindowAdded) {try {mWindowManager.removeViewImmediate(mBatteryChargeView)} catch (e: Exception) {e.printStackTrace()}mIsBarWindowAdded = false}}}}/*** 获取剩余电池容量占总容量的整数百分比*/private fun getBatteryLevel(): String {val batteryManager = mContext.getSystemService(BATTERY_SERVICE) as BatteryManagerreturn batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY).toString() + "%"}}

4. ✅ 小结

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

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


相关文章:

AR 眼镜之-充电动画定制-实现方案

目录 📂 前言 AR 眼镜系统版本 充电动画 1. 🔱 技术方案 1.1 方案介绍 1.2 实现方案 关机充电动画 亮屏/锁屏充电动画 2. 💠 关机充电动画 2.1 关机充电动画核心处理类与路径 2.2 实现细节 步骤一:1)定制 …...

AJAX-XMLHttpRequest 详解

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 前言 XMLHttpRequest 概述 主要用途 工作流程 示例代码 GET 请求示例 POST 请求示例 注意事项 工作…...

内容管理系统 Contentful 与 Baklib

对于希望管理其产品和服务的在线文档或知识库以支持其客户和员工的组织来说,市场上有太多的平台和工具。 遵循的做法之一是使用无头内容管理系统 (CMS)。 如果您是这样的组织之一,正在考虑使用无头 CMS - Contentful 之一来管理您的在线知识库&#xff0…...

[Mysql-视图和存储过程]

视图 视图是从一个或者几个基本表(或视图)导出的表。它与基 本表不同,是一个虚表。 创建使用视图 # 视图 -- 视图只能用来查询,不能做增删改 -- 创建视图 -- create view 视图名【view_xxx / v_xxx】 -- as 查询语句 create view…...

Linux下C++静态链接库的生成以及使用

目录 一.前言二.生成静态链接库三.使用静态链接库 一.前言 这篇文章简单讨论一下Linux下如何使用gcc/g生成和使用C静态链接库&#xff08;.a文件&#xff09;。 二.生成静态链接库 先看下目录结构 然后看下代码 //demo.h#ifndef DEMO_H #define DEMO_H#include<string&g…...

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网&#xff1a;http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱&#xff1a;icbctis126.com 组委会联系人&#xff1a;杨老师 19911536763 支持单位&#xff1a;中原工学院、西安工程大学、齐鲁工业大学&#xff08;山东省科学院&#xff09;、澳门…...

2024年【甘肃省安全员B证】考试资料及甘肃省安全员B证模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年甘肃省安全员B证考试资料为正在备考甘肃省安全员B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的甘肃省安全员B证模拟试题祝您顺利通过甘肃省安全员B证考试。 1、【多选题】5kW以上电动机开关箱中电…...

结合el-upload上传组件,验证文件格式及大小

结合el-upload上传组件&#xff0c;验证文件格式及大小 效果如下&#xff1a; 代码如下&#xff1a; upgradeFirmwareInfo.vue页面 <template><div><el-dialog title"新增固件升级包" :visible.sync"dialogFormVisible"top"7vh&qu…...

配置php-fpm服务

nginx(unix domain socket方式) server {listen 80;#root /test/php/publiclocation / {#URL重写 例如隐藏index.phpif (!-f $request_filename) {rewrite ^(.*)$ /index.php?s/$1 last;break;}}location ~ [^/]\.php(/|$) {#try_files $uri 404;fastcgi_index index.php;…...

科普文:Linux系统安全加固指南

本指南仅关注安全性和隐私性&#xff0c;而不关注性能&#xff0c;可用性或其他内容。 列出的所有命令都将需要root特权。以“$”符号开头的单词表示一个变量&#xff0c;不同终端之间可能会有所不同。 选择正确的Linux发行版 选择一个好的Linux发行版有很多因素。 避免分发…...

MFC开发,自定义消息

在MFC开发中&#xff0c;主要核心机制就是消息机制。QT与之类似的机制就是信号与槽。QT中的信号与槽是非常容易自定义的&#xff0c;MFC也是如此&#xff0c;自定义也是比较方便&#xff0c;况且自定义消息或者控件在整个GUI图形化界面开发中也是非常重要的部分&#xff0c;上篇…...

如何在 SpringBoot 中优雅的做参数校验?

一、故事背景 关于参数合法性验证的重要性就不多说了&#xff0c;即使前端对参数做了基本验证&#xff0c;后端依然也需要进行验证&#xff0c;以防不合规的数据直接进入服务器&#xff0c;如果不对其进行拦截&#xff0c;严重的甚至会造成系统直接崩溃&#xff01; 本文结合…...

Godot入门 03世界构建1.0版

在game场景&#xff0c;删除StaticBody2D节点&#xff0c;添加TileMap节点 添加TileSet图块集 添加TileSet源 拖动图片到图块&#xff0c;自动创建图块 使用橡皮擦擦除。取消橡皮擦后按住Shift创建大型图块。 进入选择模式&#xff0c;TileMap选择绘制&#xff0c;选中图块后在…...

GitHub每日最火火火项目(7.26)

1. 项目名称&#xff1a;meta - llama / llama3 项目介绍&#xff1a;这是 Meta Llama 3 的官方 GitHub 站点。目前尚不清楚该项目的具体功能和特点&#xff0c;但从名称推测&#xff0c;它可能与 Llama 3 模型相关&#xff0c;或许涉及到该模型的开发、训练或应用等方面。 项…...

微服务实践和总结

H5原生组件web Component Web Component 是一种用于构建可复用用户界面组件的技术&#xff0c;开发者可以创建自定义的 HTML 标签&#xff0c;并将其封装为包含逻辑和样式的独立组件&#xff0c;从而在任何 Web 应用中重复使用。 <!DOCTYPE html> <html><head…...

Spring Boot中的策略模式:优雅地处理不同商品类型的订单

引言 在开发复杂的业务系统时&#xff0c;我们经常会遇到需要根据不同条件执行不同逻辑的情况。例如&#xff0c;在电商平台中&#xff0c;可能需要根据商品的不同类型&#xff08;如电子产品、服装、食品等&#xff09;来执行不同的业务逻辑&#xff0c;比如不同的库存管理、…...

django_创建菜单(实现整个项目的框架,调包)

文章目录 前言代码仓库地址在线演示网址启动网站的时候出现错误渲染路径的一些说明文件结构网页显示一条错误路由顺序js打包出现问题的代码函数没有起作用关于进度开发细节显示不了图片梳理一下函数调用的流程修改一些宽度参数classjs 里面的一些细节让三个按钮可以点击设置按钮…...

最新全新UI异次元荔枝V4.4自动发卡系统源码

简介&#xff1a; 最新全新UI异次元荔枝V4.4自动发卡系统源码 更新日志&#xff1a; 1增加主站货源系统 2支持分站自定义支付接口 3目前插件大部分免费 4UI页面全面更新 5分站可支持对接其他分站产品 6分站客服可自定义 7支持限定优惠 图片&#xff1a; 会员中心截图&…...

PyTorch安装CUDA标准流程(可解决大部分GPU无法使用问题)

最近一段时间在研究PyTorch中的GPU的使用方法&#xff0c;之前曾经安装过CUDA&#xff0c;不过在PyTorch中调用CUDA时无法使用。考虑到是版本不兼容问题&#xff0c;卸载后尝试了其他的版本&#xff0c;依旧没有能解决问题&#xff0c;指导查阅了很多资料后才找到了解决方案。 …...

C++从入门到起飞之——初始化列表类型转换static成员 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、初始化列表 2、 类型转换 3. static成员 4、完结散花 1、初始化列表 • 之前我们实现构造函数…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...