Android O 8.0 自定义开机动画/开机铃声

2018-05-06  本文已影响1694人  CocoDoll

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

上一篇下一篇

猜你喜欢

热点阅读