android4.0.3 修改(gai)啟動動畫和開機聲(sheng)音(yin)
1. Linux 系統啟動,出現Linux小企鵝畫面(reboot)(Android 1.5及以上版本已經取消加載圖片);
2. Android平臺啟動初始化,出現"A N D R I O D"文字字樣畫面;
3. Android平臺圖形系統(tong)啟動,出現含閃動的(de)ANDROID字樣的(de)動畫圖片(start)。
現在我們(men)說的(de)是第三種方式(shi)(基于模擬器):
android開機(ji)動(dong)畫叫源碼(ma)位于frameworks/base/cmds/bootanimation下(xia),這個程(cheng)序會(hui)將(jiang)/data/local/bootanimation.zip或/system/media/bootanimation.zip里面的(de)png圖片(pian)以動(dong)畫的(de)形式(shi)播放出(chu)來。
首先,我們先來分(fen)析一(yi)下源(yuan)碼:
frameworks/base/cmds/bootanimation/BootAnimation.cpp
首先看(kan)一(yi)下定義的常量:
#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip" #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip" #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
BootAnimation::readyToRun()
進入一個if判斷語(yu)句
if ((encryptedAnimation &&
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) {
mAndroidAnimation = false;
}
BootAnimation::threadLoop()
if (mAndroidAnimation) {
r = Android(); // 執行android字體閃動的圖片
} else {
r = movie(); // 執行bootanimation.zip中提供的動畫圖片
}
==> BootAnimation::Android()會加載"images/android-logo-mask.png"和"images/android-logo-shine.png"
==> BootAnimation::movie()會加載(zai)bootanimation.zip中的內容
我們(men)下(xia)載的源碼(ma)里默(mo)認是(shi)沒(mei)有那些個.zip動(dong)畫的,所以總會(hui)跳到android字體(ti)閃動(dong)的畫面
所以(yi)如果(guo)你系(xi)那個用.zip的(de)動畫那么把你做好(hao)(hao)的(de)動畫拷貝到(dao)編譯好(hao)(hao)對應的(de)目錄下即可(ke),然后(hou)執(zhi)行make snod整合進(jin)img包就可(ke)以(yi)看到(dao)效果(guo)了
如果(guo)你想修改android閃動(dong)的(de)那兩張圖(tu)片(pian)的(de)話,最簡單的(de)方法是直接替換圖(tu)片(pian),如果(guo)你懂(dong)openGL的(de)話也可以(yi)自己做酷炫的(de)動(dong)畫
那(nei)兩張圖(tu)片放在./frameworks/base/core/res/assets/images 目(mu)錄下(xia),一(yi)張鏤空的android圖(tu),一(yi)張發光(guang)效果,動畫效果就(jiu)是下(xia)面那(nei)張發光(guang)的效果圖(tu)不斷(duan)左右(you)移動。
我是用Photoshop直接修(xiu)改的
修改完(wan)后直接替(ti)換,然(ran)后再 mmm frameworks/base , make snod 即可(ke)
以下是(shi)我(wo)修改后(hou)的效果圖:
看樣子還想那么回事
接下(xia)來我們給系統添(tian)加開機聲音(yin)
由于動畫是在(zai)BootAnimation播(bo)放的(de),所以我們的(de)聲音(yin)肯定也在(zai)這(zhe)個(ge)類中(zhong)做,照貓畫虎(hu)
首先在BootAnimation.h添加方法的聲明(ming)和頭文(wen)件的引用
#include <media/AudioSystem.h> #include <media/mediaplayer.h>
添加方法(fa) void bootMusic();
然后在BootAnimation.cpp中實(shi)現這個(ge)方法:
void BootAnimation::bootMusic()
{
int index;
MediaPlayer* mp = new MediaPlayer();
if (mp->setDataSource("/system/etc/poweron.wav", NULL) == NO_ERROR) {
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
mp->prepare();
}
AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index);
if (index != 0) {
mp->seekTo(0);
mp->start();
}
}
請注意這個目錄setDataSource("/system/etc/poweron.wav", NULL)
其實這個目錄是隨便寫的,你想(xiang)從哪(na)個目錄讀(du)這個文(wen)件就從哪(na)個目錄讀(du)好(hao)了,但是你要把(ba)這個文(wen)件放在對應的目錄下(xia)
比(bi)如,這個目(mu)錄是(shi)system/etc (這個目(mu)錄是(shi)android系(xi)統(tong)的(de)目(mu)錄,不(bu)(bu)是(shi)源(yuan)碼的(de)目(mu)錄),這個文件夾是(shi)只有(you)讀權(quan)限(xian)而沒(mei)有(you)寫權(quan)限(xian)的(de),所有(you)你不(bu)(bu)用試adb shell了,沒(mei)用的(de)
其實system/etc這個目(mu)錄對應的是我們(men)編譯(yi)后(hou)out文件夾下的xxx,然后(hou)在system/etc,所以你(ni)把poweron.wav放(fang)到這里就行了,當然如果(guo)你(ni)這時再(zai)emulaor 也(ye)同(tong)樣是看(kan)不(bu)到效果(guo)的,因為(wei)你(ni)修改完(wan)還(huan)沒(mei)有編譯(yi),和(he)上面修改圖片一(yi)樣,make snod一(yi)下
然(ran)后和圖(tu)上(shang)一樣(yang),你就(jiu)會生成新的system.img,當然(ran)你之前添加的poweron.wav也會自動被編譯進去(qu)了
然(ran)后再修改bootanimation_main.cpp這個(ge)文件,因為方法也(ye)申(shen)明了,也(ye)實現了,就(jiu)是(shi)還沒(mei)有調用,所以(yi)調用就(jiu)在這里調
//play boot music -yp
BootAnimation *animation = new BootAnimation();
animation->bootMusic();
修(xiu)改完這寫以后還需(xu)要修(xiu)改Android.mk文件
因為(wei)播(bo)放聲音還需要引入庫
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libui \
libskia \
libEGL \
libGLESv1_CM \
libgui \
libmedia
請注意(yi),libmedia是新添加(jia)的;
完事后(hou)就(jiu)ok了,當然(ran)還是(shi)需(xu)要編譯的(de)
mmm frameworks/base/cmds/bootanimation/
make snod
大(da)功告成(cheng),這樣(yang)你就成(cheng)功的添加(jia)了開機音(yin)樂
也許有人會問,那android系統自帶的那些音樂和鈴聲在什么地方呢?
源碼目(mu)錄(lu)在framworks/base/data/sounds
至于編譯(yi)完成后放到什么地方了那是Android.mk文件(jian)上配(pei)置的(de)
不(bu)過這里叫AllAudio.mk
我(wo)們可以看到他(ta)又包含了很多mk文件(jian),在同(tong)一目錄下(xia)就可以找到,上(shang)圖中(zhong)就可以,我(wo)們隨便打開一個(ge)看看
這下你們頓時明白了吧,這些資(zi)源編(bian)譯(yi)后都去(qu)了神馬地方
所以,在剛才添加poweron.wav的時候,其(qi)實可以直接把(ba)聲音資源丟到framworks/base/data/sounds這個目錄(lu)下
然后再mk文(wen)件中這(zhe)樣修改:
$(LOCAL_PATH)/poweron.wav:system/etc/poweron.wav \
不用(yong)我說(shuo),當(dang)然是執行mmm還有make snod命令(ling)了
其實還有一種(zhong)辦法(fa),如(ru)果你(ni)不想這么麻煩(fan),你(ni)可以之際把poweron.wav 文(wen)件丟到./frameworks/base/core/res/assets/sounds下,用的時候怎(zen)么用呢(ni)?
加(jia)載(zai)的時候路徑是什么呢?我們(men)看(kan)(kan)看(kan)(kan)源碼
我們可以看到之前我們修改(gai)的(de)(de)那兩張(zhang)圖片是怎么被加(jia)載進來(lai)的(de)(de)
而這(zhe)個方(fang)法的(de)兩個參數(shu)是:
是(shi)不是(shi)頓(dun)時又明白(bai)了?
原來精髓所在是(shi)有個Asset可以使用,這(zhe)個和上層開發中是(shi)一樣(yang)的(de),這(zhe)個文件夾(jia)中的(de)東西是(shi)不編譯的(de)。
Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
if (!asset)
return NO_INIT;
SkBitmap bitmap;
SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
&bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
asset->close();
delete asset;
所以按(an)照這個(ge)方法就可以找到poweron.wav 這個(ge)文件了,然后修改(gai)下bootMusic的代碼就可以了。









