Android 7 修改启动动画和开机声音
背景
在修改开机音量的时候,发现找不到对应的声音功能调用。
因此了解了一下安卓的开机声音是如何实现的。
安卓4~安卓7 都可以这么做。
参考:
- https://blog.csdn.net/chen825919148/article/details/19626241
- https://www.dazhuanlan.com/2019/08/21/5d5d166b2ed1a/
前言
关于安卓的开机效果(动画、logo、声音),有下面几个阶段:
- 老的方案1:Linux 系统启动,出现Linux小企鹅画面(reboot)(Android 1.5及以上版本已经取消加载图片);
- 沿用至今的方案2:Lndroid平台图形系统启动,出现含闪动的ANDROID字样的动画图片(start)并加载Android系统。
我们这里说的是沿用至今的方案2。
源码分析
android开机动画叫源码位于frameworks/base/cmds/bootanimation/BootAnimation.cpp中,会将/data/local/bootanimation.zip或/system/media/bootanimation.zip里面的图片(支持png、jpeg、bmp)以动画的形式播放出来:
在源码树中搜索
bootanimation.zip即可找到可供修改的开机动画。
static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";
static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";
static const char SYSTEM_ENCRYPTED_BOOTANIMATION_FILE[] = "/system/media/bootanimation-encrypted.zip";
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
if (status)
return -1;
// create the native surface andrew.hu modify
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
dinfo.orientation == 1 ? dinfo.h : dinfo.w,
dinfo.orientation == 1 ? 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;
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;
// 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(getAnimationFileName(IMG_ENC), R_OK) == 0)) {
mZipFileName = getAnimationFileName(IMG_ENC);
}
else if (access(getAnimationFileName(IMG_OEM), R_OK) == 0) {
mZipFileName = getAnimationFileName(IMG_OEM);
}
else if (access(getAnimationFileName(IMG_SYS), R_OK) == 0) {
mZipFileName = getAnimationFileName(IMG_SYS);
}
return NO_ERROR;
}
循环:
bool BootAnimation::threadLoop()
{
bool r;
// We have no bootanimation file, so we use the stock android logo
// animation.
if (mZipFileName.isEmpty()) {
r = android(); // 执行android字体闪动的图片 会加载"images/android-logo-mask.png"和"images/android-logo-shine.png"
} else {
r = movie(); // 执行bootanimation.zip中提供的动画图片
}
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;
}
所以如果你想修改动画,那么把你做好的动画拷贝到编译好对应的目录下即可,然后编译刷入整合进system镜像包就可以看到效果了
如果你想修改android闪动的那两张图片的话,最简单的方法是直接替换图片,如果你懂openGL的话也可以自己做酷炫的动画
另外如果需要修改开机logo动画,可以这么做(参考BootAnimation.cpp中的android函数):
1、将图片文件xx.png放置到 frameworks/base/core/res/assets/images中。
2、再在函数中完成对应的调用:
- 声明对应的类型:
Texture mTexture - 加载
initTexture(&mTexture, mAssets, "images/xx.png"); - 使用openGL来绘制界面(略)
添加开机声音
既然我们已经知道了关于开机效果显示的大致流程。
那么添加开机声音也很简单,我们可以使用MediaPlayer这个类来完成我们的需求。
声明与实现
首先在BootAnimation.h添加方法的声明和头文件的引用
#include <media/AudioSystem.h>
#include <media/mediaplayer.h>
添加: void bootMusic();的声明以及对应的实现
// frameworks/base/cmds/bootanimation/BootAnimation.h
class BootAnimation : public Thread, public IBinder::DeathRecipient
{
//...
private:
void bootMusic();
}
// frameworks/base/cmds/bootanimation/BootAnimation.cpp
void BootAnimation::bootMusic()
{
int index;
const char *fileName = "/system/media/boot.wav";
MediaPlayer* mp = new MediaPlayer();
audio_devices_t device = AudioSystem::getDevicesForStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
if (mp->setDataSource(NULL, fileName, NULL) == NO_ERROR)
{
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE/*AudioSystem: :ENFORCED_AUDIBLE*/);
mp->prepare();
}
LOGE ("bootMusic\n");
AudioSystem::initStreamVolume(AUDIO_STREAM_ENFORCED_AUDIBLE, 0,7);
AudioSystem::setStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, 7, device);
AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE/*AudioSystem::ENFORCED_AUDIBLE*/, &index, device);
LOGE ("index %d",index);
if (index != 0)
{
LOGD("playing %s", fileName);
mp->setVolume(0.4f, 0.4f);
mp->seekTo(0);
mp->start();
}
}
只要
fileName对应的声音文件存在而且有权限访问到,那么无所谓放在哪里。
此后,在合适的地方(android ()或者movie ())调用即可,例如:
bool BootAnimation::movie()
{
Animation* animation = loadAnimation(mZipFileName);
// ...
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);
// ...
bootMusic(); // 播放声音 (只要在播放动画之前播放即可)
playAnimation(*animation); // 播放动画
// ...
return false;
}
Android.mk
光有头文件还不够,播放声音还需要引入对应的库:
# frameworks/base/cmds/bootanimation/Android.mk
# ...
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
libandroidfw \
libutils \
libbinder \
libui \
libskia \
libEGL \
libGLESv1_CM \
libgui \
libOpenSLES \
libtinyalsa \
libregionalization \
libmedia # 注意,libmedia是新添加的;
# ...
大功告成,这样就成功的添加了开机音乐。
修改铃声
也许有人会问,那android系统自带的那些音乐和铃声在什么地方呢?
系统默认了很多的声音,如果有需要,可以修改frameworks/base/data/sounds下面文档及文档夹中的声音文档。
至于编译完成后放到什么分区那是由AllAudio.mk决定的。
AllAudio.mk的作用:是将这些音乐文档全部打包到系统system/media/audio下面各个模块的文档,然后在系统开机的时候,扫描这些文档,将其加入到数据库中,之后在设置中更换声音时,则直接从数据库中查询这些音乐文档,然后供用户选择。
如果需要添加某个铃声,可以这么做:
1、在AllAudio.mk添加一列类似这样的内容:$(LOCAL_PATH)/aaa.ogg:system/media/audio/bbb/xxx.ogg
2、再将aaa.ogg拷贝到frameworks/base/data/sounds中
修改也是类似的原理。
当然,也可以通过修改mk文件中指定的音乐文档名来实现静音等目的。
例如,
ro.config.notification_sound(通知默认的音乐文档文档名)在build/target/product/full_base.mk中定义,如果我们不想有声音那么我们可以将默认值改为不存在的文档,则不会播放通知声音了。当然我们也可以在客户定义的mk中使用PRODUCT_PROPERTY_OVERRIDES去复写此属性,将其指定为不存在文档或者为空,这样就不会有通知声音响了。
修改开机动画
这里介绍bootanimation.zip如何制作。
开机动画包内容
先看看bootanimation.zip的内容:解压.zip文件后,会有n个存放图片的文件夹(partn)+1个desc.txt文件。
开机动画压缩包不能包含bootanimation文件夹,必现是如下格式
├── desc.txt
├── part0
│ ├── 00013.png
│ ├── 00014.png
│ ├── 00052.png
└── part1
├── 00013.png
├── 00015.png
├── 00019.png
└── 00069.png
上图中的文件夹名字可随便命名(对应desc.txt即可),里面存放的就是开机要显示的图片。
desc.txt解析
打开以后可以看到是类似这样的内容。
240 320 1
p 2 0 part0
p 0 0 part1
第一行代表帧率以及动画大小:
| 240 | 320 | 1 |
|---|---|---|
| 宽 | 高 | 每秒1帧 |
此后的每一行代表每一段动画具体的效果:
| p | 2 | 0 | part0 |
|---|---|---|---|
| 代表一段动画 | 代表文件夹播放的次数,0代表永远循环 | 表示这部分播完后下部分开始的间隔 | 代表从哪个文件夹中寻找动画 |
一般来说,将最后的那段动画设置成循环播放,就可以在进入系统界面之前一直有画面,不会出现黑屏的情况(所有动画都做完了,但是还没进入到系统界面就会出现黑屏)。
最后一行是空行,代表文件结束;很多人在改动时候会把这一行删掉,如果制作以后失败了,那么可以将这一行加上去试试。
图片替换
图片需要统一格式为png,且各图片的大小需要相同。
图片的命名可以随意,但是最后的数字要有顺序。
zip制作
开机动画压缩格式必须为存储方式。
在Windows中可以在压缩时,指定压缩级别为
不压缩/存档。由于Windows下压缩软件良莠不齐,因此建议在Linux中 制作。
Linux下可以使用下列命令:
cd bootanimation
zip -0 -r ../bootanimation.zip ./*
Android 7 修改启动动画和开机声音的更多相关文章
- [转]android4.0.3 修改启动动画和开机声音
本文转自:http://www.cnblogs.com/jqyp/archive/2012/03/07/2383973.html 1. Linux 系统启动,出现Linux小企鹅画面(reboot)( ...
- Android隐藏虚拟按键,关闭开机动画、开机声音
/*********************************************************************** * Android隐藏虚拟按键,关闭开机动画.开机声音 ...
- Android 模仿微信启动动画(转)
本文内容 环境 项目结构 演示微信启动动画 本文演示微信启动动画.请点击此处下载,自行调试. 顺便抱怨一下,实践性(与研究性质的相对)技术博的“七宗罪”: 第一宗罪,错字连篇,逻辑不清: 第二宗罪,文 ...
- Android 模仿微信启动动画
本文内容 环境 项目结构 演示微信启动动画 本文演示微信启动动画.请点击此处下载,自行调试. 顺便抱怨一下,实践性(与研究性质的相对)技术博的"七宗罪": 第一宗罪,错字连篇,逻辑 ...
- Android9.0 MTK 平板横屏方案修改(强制app横屏 + 开机logo/动画+关机充电横屏 + RecoveryUI 横屏)
文章较长建议先收藏再看 拆解步骤 1.app 强制横屏显示,无视 android:screenOrientation="portrait" 属性 2.屏幕触摸坐标修改为横屏 3.开 ...
- 双系统修改启动项顺序&&&修改开机启动等待时间
1. 双系统修改启动项顺序 更改/etc/grub.d目录 下的文件名是可行的 默认情况下Windows 7对应的文件名是30_os-prober,第一个linux系统对应的是10- ...
- 修改centos6启动动画(plymouth方式)
centos6默认的启动动画是一个白蓝色的进度条,背景全黑色,现在需要对centos的启动动画进行定制 在查询了一些资料以后,发现有一个软件是可以对启动动画进行定制的,名字叫plymouth 这个在c ...
- Android4.2.2启动动画前播放视频
首先声明測试平台为瑞芯微的rk3168,Android4.2.2,Android版本号非常重要,由于Android4.0和Android4.2.2的代码有些地方就有差别,并不通用! 首先接到任务不知怎 ...
- Android核心服务解析篇(三)——Android系统的启动
从大的方面来说.Android系统的启动能够分为两个部分:第一部分是Linux核心的启动,第二部分是Android系统的启动. 第一部分主要包含系统引导,核心和驱动程序等,因为它们不属于本篇要讲的内容 ...
- phonegap配置启动动画
以下有2种方式 1 主Active中 onCreate函数里添加代码 2 config.xml文件进行配置(对通过命令行模式下cordova命令行生成的可行) 确保自己安装了SplashScreen插 ...
随机推荐
- Pinpoint对k8s关键业务模块进行全链路监控(17)
一.全链路监控概述 1.1 什么是全链路监控 在分布式微服务架构中,系统为了接收并处理一个前端用户请求,需要让多个微服务应用协同工作,其中 的每一个微服务应用都可以用不同的编程语言构建,由不同的团队开 ...
- M9K内存使用教程
M9K内存使用教程 M9K内存是Altera内嵌的高密度存储阵列.现代的FPGA基本都包含类似的不同大小的内存. M9K的每个块有8192位(包含校验位实际是9216位).配置灵活.详细了解M9K可参 ...
- 【简说Python WEB】Flask应用的单元测试
[简说Python WEB]Flask应用的单元测试 tests/test_basics.py import unittest from flask import current_app from a ...
- 04.2 go-admin前后端打包为一个服务上线
目录 一.思路: 二.打包go-admin-ui为静态文件 a.修改配置文件 b.打包 c.复制dist到go-admin的static目录里 三.配置go-admin a.配置路由 b.访问页面 视 ...
- 深度Linux deepin更新,防火墙操作
获取更新 sudo apt-get update 更新系统 sudo apt-get dist-upgrade -y 清理更新缓存 sudo apt-get autoclean 防火墙操作 sudo ...
- 一篇文章掌握Python中多种表达式的使用:算术表达式、字符串表达式、列表推导式、字典推导式、_集合推导式、_生成器表达式、逻辑表达式、函数调用表达式
Python 中的表达式可以包含各种元素,如变量.常量.运算符.函数调用等.以下是 Python 表达式的一些分类及其详细例子: 1. 算术表达式 算术表达式涉及基本的数学运算,如加.减.乘.除等. ...
- 4G EPS 中的消息类型
目录 文章目录 目录 消息 MIB(主消息块) SIBs(多个系统消息块) 系统消息的映射和调度 系统信息的更改通知 消息 LTE 的系统消息是蜂窝网络与 UE 互相交互的与 LTE 系统相关的.特殊 ...
- CodePen 的国内替代「笔.COOL」,一个功能完备、使用便捷的在线HTML/CSS/JS编辑器和作品分享平台
笔.COOL,是一个最近在国内崭露头角的在线HTML/CSS/JS编辑器和作品分享平台. 笔.COOL 提供了一个在线的 HTML.CSS 和 JavaScript 代码编辑器.无需任何安装,你只需打 ...
- python连接redis,mongodb以及简单命令使用
redis 环境如下: [root@mcw01 ~/msRedis]$ ps -ef|grep -v grep|grep redis root 46061 1 0 14:28 ? 00:00:45 r ...
- 莫烦tensorflow学习记录 (4)Classification 分类学习
MNIST 数据 首先准备数据(MNIST库) from tensorflow.examples.tutorials.mnist import input_data mnist = input_dat ...