Android O 8.0 自定义开机动画/开机铃声
1. 制作bootanimation.zip
参考解压的一个bootanimation.zip, 里面有两个文件夹一个desc.txt描述文件
两个文件夹都是开机动画的图片,desc.txt:
1080 1920 10
p 1 0 part1
p 0 0 part2
1080 1920 为分辨率, 10表示10帧每秒
p 1 0 part1 :p就是play。1是播放一次,0是无限次。0代表阶段间隔帧数为0,也就是帧动画形式播放图片。part1指定了要播放的第一个文件夹为part1(也可以取别的名称,做相应修改即可)
p 0 0 part2:第一个0表示循环播放。第二个0表示每张图片间隔帧数为0(和上面指令一样)。part2表示要循环播放的文件夹
将制作好的文件打包成bootanimation.zip即可,注意:必须是zip格式,且包的大小最好不要超过3M。然后放入/system/media/目录下即可。
最近在制作开机动画过程中发现添加开机动画后其一直不能显示,经过千辛万苦的寻找最终得出如下结论:
开机动画zip的压缩尽量在linux环境下进行,在windows或者ubuntu的UI界面下压缩 bootanimation.zip可能会造成开机动画不能显示,在linux下,进入素材目录,执行压缩命令:
zip-Z store bootanimation.zip part0/*.pngpart1/*.pngdesc.txt
Windows下打包ZIP也需要进入素材目录。例如:选中part0,part1,desc.txt三个文件,右键选择”添加到压缩文件”,选择”ZIP”压缩,“存储”模式即可。
2. 定制到系统
开机动画一般放在系统 device/xx/xx/media/bootanimation.zip,并且要在具体的项目mk文件中声明:
PRODUCT_COPY_FILES += device/xxx/$(TARGET_PRODUCT)/media/bootanimation.zip:system/media/bootanimation.zip
我们可以看出这句配置的目的是把bootanimation.zip拷贝到系统system/meida目录下.
3. 跟踪源码
surfaceflinger.rc 下启动surfaceflinger
service surfaceflinger /system/bin/surfaceflinger
-------------------------------------------------------------------------------------------------------------------
SurfaceFlinger.cpp启动动画
startBootAnim() -> mStartPropertySetThread->Start();
/frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp
bool StartPropertySetThread::threadLoop() {
// Set property service.sf.present_timestamp, consumer need check its readiness
property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
// Clear BootAnimation exit flag
property_set("service.bootanim.exit", "0");
// Start BootAnimation if not started
property_set("ctl.start", "bootanim");
// Exit immediately
return false;
}
其中先将”service.bootanim.exit”标志为 0,这个标志用于在bootanim进程中检测开机动画是否结束,
然后通过发”ctl.start”请求给init进程,启动”bootanim”服务.
-------------------------------------------------------------------------------------------------------------------
frameworks/base/cmds/bootanimation/bootanimation_main.cpp 中的main函数启动BootAnimation.cpp
onFirstRef -> readyToRun
在readyToRun 中 会有获取动画的判断 getAnimationFileName
/** Get bootup Animation File
* Parameter:
* 1.defaultfile: system default media file
* 2.isShutdown : is shutdown or boot status
* Return Value : Animation File path
**/
const char *BootAnimation::getAnimationFileName(const char * defaultfile,bool isShutdown)
{
// Load animations of Carrier through regionalization environment
if (Environment::isSupported()) {
Environment* environment = new Environment();
int isShutdownState = Environment::BOOT_STATUS;
if (isShutdown) {
isShutdownState = Environment::SHUTDOWN_STATUS;
}
const char* animFile = environment->getMediaFile(
Environment::ANIMATION_TYPE, isShutdownState);
ALOGE("Get Carrier Animation type: %d,status:%d", Environment::ANIMATION_TYPE,isShutdown);
if (animFile != NULL && strcmp(animFile, "") != 0) {
return animFile;
}else{
ALOGD("Get Carrier Animation file: %s failed", animFile);
}
delete environment;
}
return defaultfile;
}
-------------------------------------------------------------------------------------------------------------------
继续跟踪 environment->getMediaFile
在frameworks/base/libs/regionalization/Environment.cpp 我们发现 getMediaFile方法中的BOOT_SHUTDOWN_FILE 常量
static const char* BOOT_SHUTDOWN_FILE[2][2] = {
{"/system/media/bootanimation.zip", "/system/media/shutdownanimation.zip"},
{"/system/media/boot.wav", "/system/media/shutdown.wav"} };
就是我们对应的配置。
-------------------------------------------------------------------------------------------------------------------
后续就是对动画的播放BootAnimation.threadLoop 当mZipFileName
if(mZipFileName.isEmpty()) {
r = android(); //播放Android系统默认的开机动画
}
android() 播放的是系统原生动画,“android”字样加上不断移动的光影效果。
movie() 则是读取bootanimation.zip 中的帧动画,一张一张的轮播,形成动画效果。
检测到 “service.bootanim.exit” 的值被修改成1 之后,就调用 requestExit() 结束动画
期间会走到wms的enableScreenAfterBoot() ,最后调用SurfaceFlinger::bootFinished()完成开机.
---------------------------------------------分割线--------------------------------------------------
最近又多了一些增加开机铃声的需求。
这个有多种改法:1.自己添加播放 2直接使用bootAnimation
第二种比较简单:
首先我们要看下 frameworks/base/cmds/bootanimation这个目录:
我们需要添加一个audio.wav 的开机铃声.
把它放在bootanimation/part0/ 中, 然后在bootanimation/中执行打包命令:
zip -0qry -i \*.txt \*.png \*.wav @ ../bootanimation.zip *.txt part*
会生成一个bootanimation.zip然后执行
adb push bootanimation.zip /system/media
这些东西可以参考FORMAT.md 这个文件。
如果直接用的话,上述步骤已经足够,参考代码给个传送门:
https://download.csdn.net/download/zghlezh/10474732