平台:A33
Android4.4
Linux3.4
功能描述:实现重启的开机不播放开机铃声,按power键的开机播放开机铃声
一,无论关机还是重启都会经过rebootOrShutdown这个方法,在方法中通过参数reboot判断是否为重启,否则直接关机。在重启的那部分代码中新建一个文件/data/for_reboot_check.txt并写入"reboot"信息。注:文件创建在/sdcard目录中不合适,因为/sdcard目录是启动后期挂载的,在/system/目录中创建文件没有权限,所以选择在/data/目录中创建
代码路径:android/frameworks/base/services/java/com/android/server/power/ShutdownThread.java
/**
* Do not call this directly. Use {@link #reboot(Context, String, boolean)}
* or {@link #shutdown(Context, boolean)} instead.
*
* @param reboot true to reboot or false to shutdown
* @param reason reason for reboot
*/
public static void rebootOrShutdown(boolean reboot, String reason) {
if (reboot) { //if is reboot create a new file
//add by jin,create a new file to store shutdown information
//=======================================================
String filenameTemp;
String path;
FileWriter writer = null;
filenameTemp = "/data"+"/for_reboot_check" + ".txt"; //file path
File filename = new File(filenameTemp);
Log.i(TAG, "----new file-----");
try{
if(!filename.exists()){
filename.createNewFile(); //create a new file
Log.i(TAG, "------create new file:"+ filenameTemp+"-----\n");
}
writer = new FileWriter(filename, false);
writer.append("reboot"); //write data to file
Log.i(TAG, "------writer data-----\n");
writer.flush(); //flush write cache
Log.i(TAG, "flush");
writer.close(); //close writer
}catch(IOException e){
e.printStackTrace();
}finally{
if(null != writer){
}
}
//================================================================================
Log.i(TAG, "Rebooting, reason: " + reason);
try {
PowerManagerService.lowLevelReboot(reason);
} catch (Exception e) {
Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
}
} else if (SHUTDOWN_VIBRATE_MS > 0) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator();
try {
vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
} catch (Exception e) {
// Failure to vibrate shouldn't interrupt shutdown. Just log it.
Log.w(TAG, "Failed to vibrate during shutdown.", e);
}
// vibrator is asynchronous so we need to wait to avoid shutting down too soon.
try {
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
}
}
IWindowManager mWindowManager;
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
if(mWindowManager != null ){
try{
if(isFreeze==1){
mWindowManager.thawRotation();
mWindowManager.updateRotation(true, true);
mWindowManager.setEventDispatching(false);
}
}catch (RemoteException e) {
}
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown();
}
二,开机动画和开机铃声是由bootanimation应用实现的,在开机动画播放前读取/data/for_reboot_check.txt文件的内容,判断上次关机是否是重启,如果是重启则不播放开机铃声,
代码路径:android/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main(int argc, char** argv)
{
#if 1
//add by jin, for check reboot information
//=======================================================
FILE *file = NULL;
int ret = 0;
int flag = 0; //用于判断是否是重启
char buf_read[10];
file = fopen("/data/for_reboot_check.txt", "rt+");
if(file == NULL){
printf("------file open failed----\n");
//return -1;
}else{
printf("------file open sucess----\n");
ret = fread(buf_read, sizeof(char), 6, file);
if(ret != 6)
{
printf("----read failed:ret=%d----\n",ret);
}else{
printf("-----%s----\n", buf_read);
if(strncmp("reboot", buf_read, sizeof("reboot")) == 0){
printf("------cmp sucess----\n");
flag = 1; //为重启,则flag置1
if(remove("/data/for_reboot_check.txt") ==0)
printf("----remove file sucess----");
}else{
//return -1;
}
}
}
#endif
//===============================================================
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
#endif
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
char cmd[PROPERTY_VALUE_MAX];
property_get("sys.shutdown_animation", cmd, "boot");
const char* url = "/system/media/boot.wav";
if (!strcmp(cmd, "shutdown")) {
url = "/system/media/shutdown.wav";
}
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object
sp<BootAnimation> boot = new BootAnimation();
//add by jin, flag为0,则为关机后的启动,flag为1,则为重启后的启动
if(flag == 0){
boot->playBootMusic(url);
}
IPCThreadState::self()->joinThreadPool();
}
return 0;
}
推荐博客:
关于关机重启的流程分析:https://blog.csdn.net/lxl584685501/article/details/45747967
原文出处:https://www.cnblogs.com/ljin/p/10244066.html
来源:oschina
链接:https://my.oschina.net/u/4261744/blog/3271351