Android O 8.0 自定義開(kāi)機(jī)動(dòng)畫(huà)/開(kāi)機(jī)鈴聲

1.? 制作bootanimation.zip

參考解壓的一個(gè)bootanimation.zip, 里面有兩個(gè)文件夾一個(gè)desc.txt描述文件

兩個(gè)文件夾都是開(kāi)機(jī)動(dòng)畫(huà)的圖片,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是無(wú)限次。0代表階段間隔幀數(shù)為0,也就是幀動(dòng)畫(huà)形式播放圖片。part1指定了要播放的第一個(gè)文件夾為part1(也可以取別的名稱(chēng),做相應(yīng)修改即可)

p? 0? 0? part2:第一個(gè)0表示循環(huán)播放。第二個(gè)0表示每張圖片間隔幀數(shù)為0(和上面指令一樣)。part2表示要循環(huán)播放的文件夾

將制作好的文件打包成bootanimation.zip即可,注意:必須是zip格式,且包的大小最好不要超過(guò)3M。然后放入/system/media/目錄下即可。

最近在制作開(kāi)機(jī)動(dòng)畫(huà)過(guò)程中發(fā)現(xiàn)添加開(kāi)機(jī)動(dòng)畫(huà)后其一直不能顯示,經(jīng)過(guò)千辛萬(wàn)苦的尋找最終得出如下結(jié)論:

開(kāi)機(jī)動(dòng)畫(huà)zip的壓縮盡量在linux環(huán)境下進(jìn)行,在windows或者ubuntu的UI界面下壓縮 bootanimation.zip可能會(huì)造成開(kāi)機(jī)動(dòng)畫(huà)不能顯示,在linux下,進(jìn)入素材目錄,執(zhí)行壓縮命令:

zip-Z store bootanimation.zip part0/*.pngpart1/*.pngdesc.txt

Windows下打包ZIP也需要進(jìn)入素材目錄。例如:選中part0,part1,desc.txt三個(gè)文件,右鍵選擇”添加到壓縮文件”,選擇”ZIP”壓縮,“存儲(chǔ)”模式即可。

2. 定制到系統(tǒng)

開(kāi)機(jī)動(dòng)畫(huà)一般放在系統(tǒng) device/xx/xx/media/bootanimation.zip,并且要在具體的項(xiàng)目mk文件中聲明:

PRODUCT_COPY_FILES += device/xxx/$(TARGET_PRODUCT)/media/bootanimation.zip:system/media/bootanimation.zip

我們可以看出這句配置的目的是把bootanimation.zip拷貝到系統(tǒng)system/meida目錄下.

3. 跟蹤源碼

surfaceflinger.rc 下啟動(dòng)surfaceflinger

service surfaceflinger /system/bin/surfaceflinger

-------------------------------------------------------------------------------------------------------------------

SurfaceFlinger.cpp啟動(dòng)動(dòng)畫(huà)

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”標(biāo)志為 0,這個(gè)標(biāo)志用于在bootanim進(jìn)程中檢測(cè)開(kāi)機(jī)動(dòng)畫(huà)是否結(jié)束,

然后通過(guò)發(fā)”ctl.start”請(qǐng)求給init進(jìn)程,啟動(dòng)”bootanim”服務(wù).

-------------------------------------------------------------------------------------------------------------------

frameworks/base/cmds/bootanimation/bootanimation_main.cpp 中的main函數(shù)啟動(dòng)BootAnimation.cpp

onFirstRef -> readyToRun

在readyToRun 中 會(huì)有獲取動(dòng)畫(huà)的判斷 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;

}

-------------------------------------------------------------------------------------------------------------------

繼續(xù)跟蹤 environment->getMediaFile

在frameworks/base/libs/regionalization/Environment.cpp 我們發(fā)現(xiàn) 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"} };

就是我們對(duì)應(yīng)的配置。

-------------------------------------------------------------------------------------------------------------------

后續(xù)就是對(duì)動(dòng)畫(huà)的播放BootAnimation.threadLoop 當(dāng)mZipFileName

if(mZipFileName.isEmpty()) {

? ? ? r = android(); //播放Android系統(tǒng)默認(rèn)的開(kāi)機(jī)動(dòng)畫(huà)

? }

android() 播放的是系統(tǒng)原生動(dòng)畫(huà),“android”字樣加上不斷移動(dòng)的光影效果。

movie() 則是讀取bootanimation.zip 中的幀動(dòng)畫(huà),一張一張的輪播,形成動(dòng)畫(huà)效果。

檢測(cè)到 “service.bootanim.exit” 的值被修改成1 之后,就調(diào)用 requestExit() 結(jié)束動(dòng)畫(huà)

期間會(huì)走到wms的enableScreenAfterBoot() ,最后調(diào)用SurfaceFlinger::bootFinished()完成開(kāi)機(jī).

---------------------------------------------分割線--------------------------------------------------

最近又多了一些增加開(kāi)機(jī)鈴聲的需求。

這個(gè)有多種改法:1.自己添加播放 2直接使用bootAnimation

第二種比較簡(jiǎn)單:

首先我們要看下 frameworks/base/cmds/bootanimation這個(gè)目錄:


我們需要添加一個(gè)audio.wav 的開(kāi)機(jī)鈴聲.

把它放在bootanimation/part0/ 中, 然后在bootanimation/中執(zhí)行打包命令:

zip -0qry -i \*.txt \*.png \*.wav @ ../bootanimation.zip *.txt part*

會(huì)生成一個(gè)bootanimation.zip然后執(zhí)行

adb push bootanimation.zip /system/media

這些東西可以參考FORMAT.md 這個(gè)文件。

如果直接用的話,上述步驟已經(jīng)足夠,參考代碼給個(gè)傳送門(mén):

https://download.csdn.net/download/zghlezh/10474732

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容