Android 开机画面和wallpaper总结 

1 kernel的开机画面修改

1、图片需求:
图片格式:png
图片大小:1024x600(具体示lcd分辨率而定)。

2、转换图片png图片。

假设logo.png已经在目录"kernel/drivers/video/logo/logo.png"下,在kernel中依次执行一下步骤:

# cd kernel/drivers/video/logo
# pngtopnm logo.png > logo_linux.pnm
# pnmquant 224 logo_linux.pnm > logo_linux_clut224.pnm
# pnmtoplainpnm logo_linux_clut224.pnm > logo_linux_clut224.ppm

3、修改kernel config。
如果想要修改菜单配置,可以在kernel目录下执行make menuconfig;然后
进Device Drivers
进Graphics Support
进Bootop logo
进standard 224-clor Linux logo选择性加入图片

2 Android的开机画面修改

1、图片需求:
图片格式:png
图片大小:1024x600(具体示lcd分辨率而定)。
图片背景:黑色背景(推荐)

2、制作图片。
2.1 part0
将不需要重复播放的动画导成一张张的png图片(所有图片大小必须相同),依次命名为"00001.png","00002.png",...
(如 00001.png、00002.png、...、00074.png)
将整理好的图片放到"part0"目录下
2.2 part1
将不需要重复播放的动画导成一张张的png图片(所有图片大小必须相同),紧接着part0的图片名称继续命名。
(如 00075.png、00076.png)
将整理好的图片放到"part1"目录下

3、编辑"desc.txt"
如下所示:
desc.txt里面的命令格式如下:

1024 600 30
p 1 0 part0
p 0 0 part1

我逐一解释一下:

1024 600意思是说你开机动画在屏幕先以多少的分辨率显示,注意不要超过屏幕的分辨率,否则你的画面就显示不全了。
30 这个数字是代表着每秒播放的帧数,拿这个开机画面来说,part0文件夹里面共76张图片,播放时间就是76/30=2.533333秒播放完毕,当然在手机里面会有一定的延时,尤其是你的图片文件比较大的情况下,手机播快起来比较卡。
以下部分是实现画面重复位置的
p 1(代表着播放一次) 0(空指令)part0 */这句指令就代表这part0文件夹内的图片只按名称顺序播放一次
p 0(重复播放)0 (空指令)part1 */这一句指令代表着part1文件夹内的图片会循环反复播放

还有一种是指令不常用,下面也解释一下:

p 0 10 part1 这里面的那个10代表着播放完part1文件夹内的图片一遍之后稍作停顿,然后再循环播放一遍,再停顿少许,再播放,再停顿稍许·········重复下去
p 1 10 part1 同理,这句代表着播放完part1文件夹内的图片之后稍作停顿然后继续执行吓一条命令。

4、打包
必须在"windows"系统下,将"part0"、"part1"、"desc.txt"一起打包成"bootanimation.zip"。
打包的时候,必须是"zip"格式,而且压缩方式是“存储”。否则,android不能识别到,会出现黑屏!

5、动画测试
5.1 将制作好的"bootanimation.zip"通过adb导入到android进行测试,命令如下。
# adb remount
# adb push bootanimation.zip /system/media/bootanimation.zip
# adb reboot
5.2 若不需要"bootanimation.zip"动画,直接将"bootanimation.zip"从"system/media"中删除即可。

3 android的默认墙纸修改

1、Android默认墙纸的路径:

frameworks/base/core/res/res/drawable/default_wallpaper.jpg

路径根据工程的不同可以稍微有点变化;具体图片的大小,可以参考原图or根据分辨率计算。

2、同步墙纸到“墙纸设置”选项中

下面解释一下将“修改的墙纸”同步到Launcher2的墙纸设置选项中

2.1 找到Laucher2中实际使用的墙纸和对应的配置文件。例如:
墙纸的配置文件路径,
packages/apps/Launcher2/res/values-sw720dp/wallpapers.xml
墙纸的路径:
packages/apps/Launcher2/res/drawable-sw720dp-nodpi/wallpaper_architecture.jpg
packages/apps/Launcher2/res/drawable-sw720dp-nodpi/wallpaper_architecture_small.jpg

2.2 根据已有的图片,来制作实际的图片。

附录一 android的开机动画流程

1、开机动画程序bootanimation
程序目录:frameworks/base/cmds/bootanimation
主要文件:frameworks/base/cmds/bootanimation/BootAnimation.cpp
调用位置: 在init.rc中调用bootanimation

2、bootanimation流程
2.1 显示方式
判断是否存在"/data/local/bootanimation.zip"或"/system/media/bootanimation.zip",
若存在的话,则显示bootanimation.zip中的动画;
若不存在的话,则显示系统默认的android闪动画面。
具体的代码(在BootAnimation.cpp中):
--> readyToRun()中判断bootanimation.zip是否存在
    --> threadLoop()中根据mAndroidAnimation的值,来区分不同的显示方式
        --> 若mAndroidAnimation为true,则显示默认的动画,调用android()
              若mAndroidAnimation为false,则显示bootanimation.zip中的动画,调用movie()

3、程序代码
BootAnimation.cpp如下:

 /*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #define LOG_TAG "BootAnimation" #include <stdint.h>
#include <sys/types.h>
#include <math.h>
#include <fcntl.h>
#include <utils/misc.h>
#include <signal.h> #include <cutils/properties.h> #include <androidfw/AssetManager.h>
#include <binder/IPCThreadState.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/threads.h> #include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/DisplayInfo.h>
#include <ui/FramebufferNativeWindow.h> #include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h> #include <core/SkBitmap.h>
#include <core/SkStream.h>
#include <images/SkImageDecoder.h>
#include <media/mediaplayer.h> #include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/eglext.h> #include "BootAnimation.h" #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"
#define USER_SHUTDOWN_BOOTANIMATION_FILE "/data/local/shutdownanimation.zip"
#define SYSTEM_SHUTDOWN_BOOTANIMATION_FILE "/system/media/shutdownanimation.zip"
#define EXIT_PROP_NAME "service.bootanim.exit"
#define BOOTMUSIC_FILE "/system/media/audio/boot.ogg" //add by cjf
#define BOOTANIMATION_VIDEO "/system/media/bootanimation.mp4" #define FIXED_ONE 1 extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
const struct timespec *request,
struct timespec *remain); namespace android { // --------------------------------------------------------------------------- BootAnimation::BootAnimation() : Thread(false)
{
mSession = new SurfaceComposerClient();
mHardwareRotation = 0;
mFakeRotation = false;
mShutdown = false;
char property[PROPERTY_VALUE_MAX];
if (property_get("ro.sf.hwrotation", property, "0") > 0) {
mHardwareRotation = atoi(property);
} if (property_get("ro.sf.fakerotation", property, "false") > 0) {
mFakeRotation = !strcmp(property, "true");
}
mReverseAxis = mFakeRotation;
} BootAnimation::~BootAnimation() {
} void BootAnimation::isShutdown(bool shutdown) {
mShutdown = shutdown;
} void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);
}
} sp<SurfaceComposerClient> BootAnimation::session() const {
return mSession;
} void BootAnimation::binderDied(const wp<IBinder>& who)
{
// woah, surfaceflinger died!
ALOGD("SurfaceFlinger died, exiting..."); // calling requestExit() is not enough here because the Surface code
// might be blocked on a condition variable that will never be updated.
kill( getpid(), SIGKILL );
requestExit();
} status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
const char* name) {
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; // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); GLint crop[4] = { 0, h, w, -h };
texture->w = w;
texture->h = h; glGenTextures(1, &texture->name);
glBindTexture(GL_TEXTURE_2D, texture->name); switch (bitmap.getConfig()) {
case SkBitmap::kA8_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
GL_UNSIGNED_BYTE, p);
break;
case SkBitmap::kARGB_4444_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
GL_UNSIGNED_SHORT_4_4_4_4, p);
break;
case SkBitmap::kARGB_8888_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
break;
case SkBitmap::kRGB_565_Config:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
break;
default:
break;
} glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); return NO_ERROR;
} status_t BootAnimation::initTexture(void* buffer, size_t len)
{
//StopWatch watch("blah"); SkBitmap bitmap;
SkMemoryStream stream(buffer, len);
SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
codec->setDitherImage(false);
if (codec) {
codec->decode(&stream, &bitmap,
SkBitmap::kARGB_8888_Config,
SkImageDecoder::kDecodePixels_Mode);
delete codec;
} // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); GLint crop[4] = { 0, h, w, -h };
int tw = 1 << (31 - __builtin_clz(w));
int th = 1 << (31 - __builtin_clz(h));
if (tw < w) tw <<= 1;
if (th < h) th <<= 1; mBMPWidth = w;
mBMPHeight = h;
mTexWidth = tw;
mTexHeight = th; switch (bitmap.getConfig()) {
case SkBitmap::kARGB_8888_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
}
break; case SkBitmap::kRGB_565_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
}
break;
default:
break;
} glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); return NO_ERROR;
} //add by cjf
status_t BootAnimation::initTexture(SkBitmap bitmap)
{ // ensure we can call getPixels(). No need to call unlock, since the
// bitmap will go out of scope when we return from this method.
bitmap.lockPixels(); const int w = bitmap.width();
const int h = bitmap.height();
const void* p = bitmap.getPixels(); GLint crop[4] = { 0, h, w, -h };
int tw = 1 << (31 - __builtin_clz(w));
int th = 1 << (31 - __builtin_clz(h));
if (tw < w) tw <<= 1;
if (th < h) th <<= 1; mBMPWidth = w;
mBMPHeight = h;
mTexWidth = tw;
mTexHeight = th; switch (bitmap.getConfig()) {
case SkBitmap::kARGB_8888_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
GL_UNSIGNED_BYTE, p);
}
break; case SkBitmap::kRGB_565_Config:
if (tw != w || th != h) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, p);
}
break;
default:
break;
} glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); return NO_ERROR;
} status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets(); DisplayInfo dinfo;
status_t status = session()->getDisplayInfo(0, &dinfo);
if (status)
return -1; // create the native surface
sp<SurfaceControl> control = session()->createSurface(
0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction(); sp<Surface> s = control->getSurface();
// initialize opengl and egl
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
EGLint w, h, dummy;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), NULL);
context = eglCreateContext(display, config, NULL, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
return NO_INIT; mDisplay = display;
mContext = context;
mSurface = surface;
mWidth = w;
mHeight = h;
mFlingerSurfaceControl = control;
mFlingerSurface = s; mAndroidAnimation = true; // If the device has encryption turned on or is in process
// of being encrypted we show the encrypted boot animation.
char decrypt[PROPERTY_VALUE_MAX];
property_get("vold.decrypt", decrypt, ""); bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt); 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;
}
if (!mShutdown) {
status_t err = mZip.open("/data/local/bootanimation.zip");
if (err != NO_ERROR) {
err = mZip.open("/system/media/bootanimation.zip");
if (err != NO_ERROR) {
mAndroidAnimation = true;
}
} //add by cjf
mMovie = SkMovie::DecodeFile("/system/media/bootanimation.gif");
if (mMovie) {
mGifAnimation = true;
}
if (access(BOOTANIMATION_VIDEO, R_OK) == 0) {
mVideo = true;
} } else {
status_t err = mZip.open("/data/local/shutdownanimation.zip");
if (err != NO_ERROR) {
err = mZip.open("/system/media/shutdownanimation.zip");
if (err != NO_ERROR) {
mAndroidAnimation = true;
}
}
}
return NO_ERROR;
} bool BootAnimation::threadLoop()
{
bool r; //add by cjf
if (mVideo) {
r = video();
} else if (mGifAnimation) {
r = gifMovie();
} else if (mAndroidAnimation) {
r = android();
} else {
r = movie();
} // No need to force exit anymore
property_set(EXIT_PROP_NAME, "0"); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
IPCThreadState::self()->stopProcess();
return r;
} void BootAnimation::getTexCoordinate() { GLfloat w_scale = float(mBMPWidth)/mTexWidth;
GLfloat h_scale = float(mBMPHeight)/mTexHeight; if (mFakeRotation) {
mTexCoords[0]=0; mTexCoords[1]=FIXED_ONE*h_scale;
mTexCoords[2]=0; mTexCoords[3]=0;
mTexCoords[4]=FIXED_ONE*w_scale; mTexCoords[5]=0;
mTexCoords[6]=FIXED_ONE*w_scale; mTexCoords[7]=FIXED_ONE*h_scale;
} else {
mTexCoords[0]=0; mTexCoords[1]=0;
mTexCoords[2]=FIXED_ONE*w_scale; mTexCoords[3]=0;
mTexCoords[4]=FIXED_ONE*w_scale; mTexCoords[5]=FIXED_ONE*h_scale;
mTexCoords[6]=0; mTexCoords[7]=FIXED_ONE*h_scale;
}
} void BootAnimation::playMusic()
{
sp<MediaPlayer> mp = new MediaPlayer();
if ((0 == access(BOOTMUSIC_FILE, F_OK)) && mp != NULL) {
mp->setDataSource(BOOTMUSIC_FILE, NULL);
mp->prepare();
mp->start();
}
} bool BootAnimation::android()
{
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
mBMPWidth = mTexWidth = mBMPHeight = mTexHeight = 1;
getTexCoordinate();
int first = true; // to add startup music
#ifdef BOOTMUSIC_FILE
playMusic();
#endif // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); // Blend state
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (mReverseAxis) {
exchangeParameters(&mWidth, &mHeight);
} GLfloat xc = float(mWidth - mAndroid[0].w) / 2;
GLfloat yc = float(mHeight - mAndroid[0].h) / 2; if (mReverseAxis) {
exchangeParameters(&xc, &yc);
exchangeParameters(&mAndroid[0].w, &mAndroid[0].h);
exchangeParameters(&mAndroid[1].w, &mAndroid[1].h);
} const GLfloat mask_vertices[] = {
xc, yc, 0,
xc+mAndroid[0].w, yc, 0,
xc+mAndroid[0].w, yc+mAndroid[0].h, 0,
xc, yc+mAndroid[0].h, 0
}; const GLfloat shine_vertices[] = {
xc, yc, 0,
xc+mAndroid[1].w, yc, 0,
xc+mAndroid[1].w, yc+mAndroid[1].h, 0,
xc, yc+mAndroid[1].h, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);
glScissor(updateRect.left, updateRect.top, updateRect.width(),
updateRect.height()); const nsecs_t startTime = systemTime();
do {
nsecs_t now = systemTime();
double time = now - startTime;
float t = 0;
GLint x, y, offset; if (mReverseAxis) {
t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].h;
offset = (1 - (t - floorf(t))) * mAndroid[1].h;
y = yc - offset;
} else {
t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
offset = (1 - (t - floorf(t))) * mAndroid[1].w;
x = xc - offset;
} glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST); if (mReverseAxis) {
glTranslatef(0, -offset, 0);
} else {
glTranslatef(-offset, 0, 0);
}
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
glVertexPointer(3, GL_FLOAT, 0, shine_vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); if (mReverseAxis) {
glTranslatef(0, mAndroid[1].h, 0);
} else {
glTranslatef(mAndroid[1].w, 0, 0);
}
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); if (mReverseAxis) {
glTranslatef(0, offset - mAndroid[1].h, 0);
} else {
glTranslatef(offset - mAndroid[1].w, 0, 0);
} glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
glVertexPointer(3, GL_FLOAT, 0, mask_vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
if (res == EGL_FALSE)
break; // 12fps: don't animate too fast to preserve CPU
const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
if (sleepTime > 0)
usleep(sleepTime); checkExit();
} while (!exitPending()); glDeleteTextures(1, &mAndroid[0].name);
glDeleteTextures(1, &mAndroid[1].name);
return false;
} void BootAnimation::checkExit() {
// Allow surface flinger to gracefully request shutdown
if(mShutdown)//shutdown animation
{
return;
}
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
}
} bool BootAnimation::movie()
{
#ifdef BOOTMUSIC_FILE
playMusic();
#endif
ZipFileRO& zip(mZip); size_t numEntries = zip.getNumEntries();
ZipEntryRO desc = zip.findEntryByName("desc.txt");
FileMap* descMap = zip.createEntryFileMap(desc);
ALOGE_IF(!descMap, "descMap is null");
if (!descMap) {
return false;
} String8 desString((char const*)descMap->getDataPtr(),
descMap->getDataLength());
char const* s = desString.string(); Animation animation; // Parse the description file
for (;;) {
const char* endl = strstr(s, "\n");
if (!endl) break;
String8 line(s, endl - s);
const char* l = line.string();
int fps, width, height, count, pause;
char path[256];
char pathType;
if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
//LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
if (mReverseAxis) {
animation.width = height;
animation.height = width;
} else {
animation.width = width;
animation.height = height;
}
animation.fps = fps;
}
else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
//LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
Animation::Part part;
part.playUntilComplete = pathType == 'c';
part.count = count;
part.pause = pause;
part.path = path;
animation.parts.add(part);
} s = ++endl;
} // read all the data structures
const size_t pcount = animation.parts.size();
for (size_t i=0 ; i<numEntries ; i++) {
char name[256];
ZipEntryRO entry = zip.findEntryByIndex(i);
if (zip.getEntryFileName(entry, name, 256) == 0) {
const String8 entryName(name);
const String8 path(entryName.getPathDir());
const String8 leaf(entryName.getPathLeaf());
if (leaf.size() > 0) {
for (int j=0 ; j<pcount ; j++) {
if (path == animation.parts[j].path) {
int method;
// supports only stored png files
if (zip.getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) {
if (method == ZipFileRO::kCompressStored) {
FileMap* map = zip.createEntryFileMap(entry);
if (map) {
Animation::Frame frame;
frame.name = leaf;
frame.map = map;
Animation::Part& part(animation.parts.editItemAt(j));
part.frames.add(frame);
}
}
}
}
}
}
}
} // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2;
const int yc = ((mHeight - animation.height) / 2);
nsecs_t lastFrame = systemTime();
nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); const GLfloat vertices[] = {
xc, yc, 0,
xc+animation.width, yc, 0,
xc+animation.width, yc+animation.height, 0,
xc, yc+animation.height, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); for (int i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) {
// Exit any non playuntil complete parts immediately
if(exitPending() && !part.playUntilComplete)
break; for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime(); if (r > 0) {
glBindTexture(GL_TEXTURE_2D, frame.tid);
} else {
if (part.count != 1) {
glGenTextures(1, &frame.tid);
glBindTexture(GL_TEXTURE_2D, frame.tid);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
initTexture(
frame.map->getDataPtr(),
frame.map->getDataLength()); getTexCoordinate();
} if (!clearReg.isEmpty()) {
Region::const_iterator head(clearReg.begin());
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
const Rect& r(*head++);
glScissor(r.left, mHeight - r.bottom,
r.width(), r.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
} glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime();
nsecs_t delay = frameDuration - (now - lastFrame);
//ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
lastFrame = now; if (delay > 0) {
struct timespec spec;
spec.tv_sec = (now + delay) / 1000000000;
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
} checkExit();
} usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit
if(exitPending() && !part.count)
break;
} // free the textures for this part
if (part.count != 1) {
for (int j=0 ; j<fcount ; j++) {
const Animation::Frame& frame(part.frames[j]);
glDeleteTextures(1, &frame.tid);
}
}
} return false;
} bool BootAnimation::video()
{
const float MAX_FPS = 60.0f;
const bool LOOP = true;
const float CHECK_DELAY = ns2us(s2ns(1) / MAX_FPS); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(mDisplay, mSurface); float asp = 1.0f * mWidth / mHeight;
SurfaceComposerClient::openGlobalTransaction();
mFlingerSurfaceControl->setPosition(mWidth, 0);
mFlingerSurfaceControl->setMatrix(0, 1 / asp, -asp, 0);
SurfaceComposerClient::closeGlobalTransaction(); sp<MediaPlayer> mp = new MediaPlayer();
mp->setDataSource(BOOTANIMATION_VIDEO, NULL);
mp->setLooping(true);
mp->setVideoSurfaceTexture(mFlingerSurface->getSurfaceTexture());
mp->prepare();
mp->start();
while(true) {
if(exitPending())
break;
usleep(CHECK_DELAY);
checkExit();
}
mp->stop();
return false;
} //add by cjf
bool BootAnimation::gifMovie()
{
#ifdef BOOTMUSIC_FILE
playMusic();
#endif
GLuint texture = 0;
SkMSec duration = mMovie->duration();
int width = mMovie->width();
int height = mMovie->height(); const float SPEED = 1.0f;
const float MAX_FPS = 60.0f;
const bool LOOP = true;
const SkMSec LOOP_DELAY = 3000; // clear screen
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glViewport(0, 0, mWidth, mHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = mWidth / mHeight;
glFrustumf(-ratio, ratio, -1, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrthof(0, mWidth, mHeight, 0, 0, 1); glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (mReverseAxis) {
exchangeParameters(&width, &height);
} const int xc = (mWidth - width) / 2;
const int yc = ((mHeight - height) / 2);
nsecs_t frameDuration = s2ns(1) / MAX_FPS; Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+width, yc+height)); const GLfloat vertices[] = {
xc, yc, 0,
xc+width, yc, 0,
xc+width, yc+height, 0,
xc, yc+height, 0
}; const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
int nelem = sizeof(indices)/sizeof(indices[0]); glBindTexture(GL_TEXTURE_2D, 0); nsecs_t firstFrame = systemTime(); while (true) {
if(exitPending())
break;
nsecs_t lastFrame = systemTime(); SkMSec time = SPEED * (lastFrame - firstFrame) / 1000000; if (LOOP & time >= duration) {
usleep(LOOP_DELAY * 1000);
firstFrame = systemTime();
time = 0;
} mMovie->setTime(time); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
initTexture(mMovie->bitmap());
getTexCoordinate(); if (!clearReg.isEmpty()) {
Region::const_iterator head(clearReg.begin());
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
const Rect& r(*head++);
glScissor(r.left, mHeight - r.bottom,
r.width(), r.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
} glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime();
nsecs_t delay = frameDuration - (now - lastFrame);
lastFrame = now; if (delay > 0) {
struct timespec spec;
spec.tv_sec = (now + delay) / 1000000000;
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
} while (err<0 && errno == EINTR);
} checkExit();
glDeleteTextures(1, &texture);
} return false;
} // --------------------------------------------------------------------------- }
; // namespace android

Android 开机画面和wallpaper总结的更多相关文章

  1. 修改android 开机画面

    对于使用安卓手机的人来说,能够自由定制手机的各种界面是每个用户之所以喜欢安卓系统的最根本的缘由,比如手机的开机界面中的bootanimation.zip文件.本文就如何修改开机界面,做一个简单的流程介 ...

  2. Android 开机动画启动过程详解

    Android 开机会出现3个画面: 1. Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本已经取消加载图片): 2. Android平台启动初始化,出 ...

  3. Android开机logo修改方法 【转】

    本文转载自:http://blog.csdn.net/qq258711519/article/details/7766303 一体机平台开机logo修改方法 1:修改Kernel中的Logo: 若是要 ...

  4. Android开机动画、logo、字样的定制过程【转】

    本文转载自:http://blog.csdn.net/yinhaide/article/details/43668401 Android开机画面总共有三屏 一.第一屏:开机logo 1.选张png格式 ...

  5. [转载]Android系统开机画面的实现

    Android系统开机画面分为下面三个阶段: 1.开机图片:Android内核是基于标准内核的,对linux比较熟悉,特别是在开发板上移植过Linux系统的人就知道在内核引导过程中会显 示出一 个小企 ...

  6. 二 Android Studio 打包EgretApp (开机画面、横竖屏、调试、和原生交互)

    测试环境: Windows7 Egret Engine 5.0.14 Egret support 5.0.12 Android Studio 2.3 目录: 一 修改开机画面 二 横竖屏设置 三 修改 ...

  7. 源码中修改Android的开机画面和动画【转】

    本文转载自:http://blog.csdn.net/dddxxxx/article/details/54343976 参照文章:http://blog.csdn.net/a345017062/art ...

  8. Android 开机动画源码分析

    Android系统在启动SystemServer进程时,通过两个阶段来启动系统所有服务,在第一阶段启动本地服务,如SurfaceFlinger,SensorService等,在第二阶段则启动一系列的J ...

  9. OpenGL—Android 开机动画源码分析二

    引自http://blog.csdn.net/luoshengyang/article/details/7691321/ BootAnimation类的成员函数的实现比较长,我们分段来阅读: 第三个开 ...

随机推荐

  1. SSL邮件发送(腾讯企业邮箱测试通过,可以支持多附件)

    参考网址:http://www.cnblogs.com/LUA123/p/5575134.html ,谢谢! package net.common.utils.common; import java. ...

  2. poj 2253 一条路径中的最大边 再找出最小的

    题目大意,有两只青蛙,分别在两个石头上,青蛙A想要到青蛙B那儿去,他可以直接跳到B的石头上,也可以跳到其他石头上,再从其他石头跳到B那儿,求青蛙从A到B的所有路径中最小的Frog Distance,我 ...

  3. oracle的sql语句大小写

    我相信大家都知道,oracle数据库是区分大小写的,而且oracle的默认为大写的,也就是说你在sql脚本上面写的sql语句,oracle运行的时候,它会自动转化为大写的.注意一下,我这里举例子的计算 ...

  4. Qt_mingw搭建opencv开发环境

    Qt在windows下共有2个版本:mingw和msvc.其中mingw使用gcc编译器,msvc使用微软的VC编译器.针对不同版本Qt,使用Opencv的方式也不同. 区别 msvc, 可以使用op ...

  5. weex官方demo weex-hackernews代码解读(上)

    一.介绍 weex 是阿里出品的一个类似RN的框架,可以使用前端技术来开发移动应用,实现一份代码支持H5,IOS和Android.最新版本的weex已默认将vue.js作为前端框架,而weex-hac ...

  6. hadoop日志数据分析开发步骤及代码

    日志数据分析:1.背景1.1 hm论坛日志,数据分为两部分组成,原来是一个大文件,是56GB:以后每天生成一个文件,大约是150-200MB之间:1.2 日志格式是apache common日志格式: ...

  7. spark优化之并行度

    这个其实我前面已经记录过了,这里在记录一下. 我可以通过参数人为的来控制分区大小,增加分区中即可增加任务的并行度,并行度高自然运行的就快了嘛. 官方推荐集群中每个cpu并行的任务是2-3个(也就是2- ...

  8. sqlite读写

    #coding=utf-8 import sqlite3 import os #创建数据库和游标 if os.path.exists(' test.db'): conn=sqlite3.connect ...

  9. 数据库简单练习 建表+select

    create table student ( sno int primary key, sname char(20),  sex char(2), birthday datetime, class i ...

  10. canvas入门级小游戏《开关灯》思路讲解

    游戏很简单,10行10列布局,每行每列各10盏灯,游戏初始化时随机点亮其中一些灯,点击某盏灯,其上下左右的灯及本身状态反转,如果点击前是灭着的,点击后即点亮,将所有灯全部点亮才算过关.游戏试玩: 下面 ...