Android 开关机动画修改

Android 原生开机动画是以.zip图片格式,保存在system/media目录下,开关机分别对应bootanimation.zip和shutdownanimation.zip。压缩包中包含,part0、part1两个图片文件夹和一个描述文件desc.txt。txt格式如下:
1080 2280 6 (表示分辨率、帧率)
p 1 0 part0 (1表示播放1次,0表示到下一部分间隔)
p 0 0 part1 (0表示播放次数,0表示不循环)

正常的我们替换掉这个资源包就可以达到替换动画的目的。如果需要播放视频的话(视频不能太长,优点是保证音画严格同步效果),那需要一点小改动。
开机动画相关代码路径:frameworks\base\cmds\bootanimation
主要的处理逻辑都在bootanimation.cpp中,代码片段如下:·

#include <android/log.h>
#include <media/IMediaHTTPService.h>
#include <media/AudioSystem.h>//视频文件名
static const char SYSTEM_BOOT_VIDEO_FILE[] = "/system/media/boot.ts";
static const char SYSTEM_SHUTDOWN_VIDEO_FILE[] = "/system/media/shutdown.ts";
//播放状态
static bool playComplete;......bool BootAnimation::threadLoop()
{bool r;// We have no bootanimation file, so we use the stock android logo// If the device is in ffbm mode, then start fastmmi servicechar odm_fastmmi[PROPERTY_VALUE_MAX];property_get("ro.bootmode", odm_fastmmi, "");if(!strncmp("ffbm-01", odm_fastmmi,7)){property_set("ctl.start", "fastmmi");}//这里开始判断是否播放视频文件,条件随便加了,其实应该两个路径都判断下if (access(SYSTEM_BOOT_VIDEO_FILE, R_OK) == 0) {mVideo = true;} else {mVideo = false;}__android_log_print(ANDROID_LOG_INFO , "BootAnimation", "mVideo = %d", mVideo);// animation.if (mVideo) {r = video();       //这个使我们加的播放视频的} else if (!mZipFileName.isEmpty()) {r = movie();       //这个是播放zip图片的} else {r = android();     //这个是android默认的}//END......}//添加MediaPlayerListener子类,监听播放状态
class MPListener: public MediaPlayerListener
{
public:void notify(int msg, int ext1, int ext2, const Parcel *obj){__android_log_print(ANDROID_LOG_INFO , "BootAnimation", "MediaPlayer::notify :%d, %d, %d, %p", msg, ext1, ext2, obj);if (msg == MEDIA_PLAYBACK_COMPLETE) {playComplete = true;} else {playComplete = false;}}
};
//获取属性值
int getProperty(const char *str) {char buf[PROP_VALUE_MAX];property_get(str, buf, "0");return atoi(buf);
}
// 添加video函数
bool BootAnimation::video() 
{int duration = getProperty("ro.shutdown_animation.duration") / 1000; //这个是为了关机动画效果,避免出现播放完了release资源后显示桌面,加一个延迟const float MAX_FPS = 60.0f;const float CHECK_DELAY = ns2us(s2ns(1) / MAX_FPS);sp<IMediaHTTPService> httpService;eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);eglDestroySurface(mDisplay, mSurface);playComplete = false;sp<MediaPlayer> mp = new MediaPlayer();sp<MediaPlayerListener> mpl = new MPListener();mp->reset();__android_log_print(ANDROID_LOG_INFO , "BootAnimation", "mp->start() : %s", android::base::GetProperty("sys.powerctl", "").c_str());//判断是播放开机动画还是关机动画bool shutting = !android::base::GetProperty("sys.powerctl", "").empty();if (shutting) {mp->setDataSource(httpService, SYSTEM_SHUTDOWN_VIDEO_FILE, NULL);} else {mp->setDataSource(httpService, SYSTEM_BOOT_VIDEO_FILE, NULL);}mp->setLooping(false);mp->setListener(mpl);mp->setVideoSurfaceTexture(mFlingerSurface->getIGraphicBufferProducer());mp->prepare();mp->start();__android_log_print(ANDROID_LOG_INFO , "BootAnimation", "mp->start() : %d", shutting);bool stop = false;while(true) {if(exitPending())     //checkExit()确定可以结束,我们可以跳出循环break;if (stop) {checkExit();      //这个是check是否可以退出boot动画,当系统已经完成开机了continue;}if (playComplete) {   //保证视频播放完毕mp->pause();stop = true;}}if (shutting) sleep(duration);__android_log_print(ANDROID_LOG_INFO , "BootAnimation", "mp->stop() : %f", CHECK_DELAY);mp->stop();mp->disconnect();mp.clear();return false;
}

在frameworks/base/cmds/bootanimation/BootAnimation.h头文件中加下

     bool android();bool movie();//新加两个声明bool video();bool mVideo;

frameworks/base/cmds/bootanimation/Android.mk中需要加libmedia

LOCAL_SHARED_LIBRARIES := \...libmedia  

frameworks/base/cmds/bootanimation/bootanim.rc这里修改很重要

 service bootanim /system/bin/bootanimationclass core animation(user graphics改成下面,使用media服务播放才能保证音画同步)user mediagroup graphics audiodisabledoneshotwritepid /dev/stune/top-app/tasks(添加关机启动动画)
on property:persist.sys.boot_start=1start bootanim

可能关机是默认的进度条样式,没有动画,那还需要修改frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java文件,去掉进度条dialog,添加关机动画时长之类的,修改比较简单,不多赘述