android系统恢复出厂设置和升级界面的修改方法
2018-01-10 10:48
1856 查看
最近需要定制恢复出厂设置和升级的画面,将原生的绿色机器人改成其他的图片。
基于的android版本是4.4.4,改起来挺简单的,但是遇到了几个坑,特地记录下。
android 4.4.4的升级机器人图片是由两部分构成的:静态部分和动态部分。
icon_installing.png
icon_installing_overlay01.png
静态部分提供了一个大的背景图icon_install.png,动态部分是在背景图上进行覆盖的7张小图片installationOverlay01-07.png,实现机器人肚子上旋转的动画。
整体这部分的代码路径是在platform/bootable/recovery下,主要涉及的类是screen_ui.cpp
修改的思路是替换installationOverlay01-07.png图片为自己需要的图片,然后修改installationOverlay01-07.png显示的坐标位置,同时调整一下下方progressbar的高度和文字的高度,实现整体协调的效果。
修改installationOverlay01-07.png的具体位置:
修改progressbar的具体高度:
修改升级和恢复出厂界面下文字的位置:
动画播放的频率默认是1秒钟20帧。如果修改可以在这里改:
遇到的坑主要有两个。
第一个就是在替换图片的时候,最开始替换的图片的位深度跟原始图片的位深度不一致,导致图片进去后花屏,后来查清楚了原来是图片位深度引起的,所以在替换图片的时候如果图片被不正常的拉伸了,可以看下是否是位深度不一样导致的。
第二个就是遇到了一个奇怪的现象,每次烧写之后如果直接升级的话,升级的界面显示总是跟自己改的不一样,但是如果烧写后恢复出厂的话,然后再次升级,则界面显示是完全ok的,这个问题也查了很久最终定位在recovery模式下的语言locale上,因为升级调用启动程序是自己写的,在往/cache/recovery/command写入升级命令的时候只写了--update_package命令,并没有给指定--locale=en_US或是--locale=zh_CN,所以recovery模式并未识别到语言环境,导致影响了screen_ui.cpp中关于textHeight的计算,而textHeight的数值又影响了图片以及文字的高度设置,所以看起来不会按照自己设置的方式来改变。
升级时的语言识别的逻辑是这样的:
首先进入recovery模式后,在执行Recovery.cpp的main函数时,会对/cache/recovery/command写入的命令进行逐行解析,当解析到locale的时候,就会将当前升级操作的locale设置为读到的内容,当没有在command中读到locale的时候,系统会走load_locale_from_cache()函数,来获取上一次我们是否在/cache/recovery/last_locale中写入了之前的语言环境,如果还是没有的话,locale就真的找不到了,text的高度是根据locale来获取的,这时候就会影响text的高度的值,从而导致升级界面出现问题。
那为什么先恢复出厂设置后再升级就没问题了呢?原因是恢复出厂设置的最后一步会在/cache/recovery/last_locale中写入语言环境,这样在下次升级的时候就可以找到一个语言的依据,也就不会导致text高度出现问题。
刚开始接触底层,有些可能说的不对,希望自己对底层一点点的熟悉起来。对于这部分的代码可以通过LOGI来进行log输出,然后在恢复出厂后在/cache/recovery/last_log中查看到自己打印的log信息。
另外看了下android 7.1的这部分的代码,发现貌似已经可以利用max_stage是否为-1来控制不显示图片,只显示文字了。
最后附上两个博客,对了解recovery模式和recovery模式的界面描画很有帮助。
http://blog.csdn.net/u010223349/article/details/40392789 http://blog.csdn.net/fengying765/article/details/38301895
基于的android版本是4.4.4,改起来挺简单的,但是遇到了几个坑,特地记录下。
android 4.4.4的升级机器人图片是由两部分构成的:静态部分和动态部分。
icon_installing.png
icon_installing_overlay01.png
静态部分提供了一个大的背景图icon_install.png,动态部分是在背景图上进行覆盖的7张小图片installationOverlay01-07.png,实现机器人肚子上旋转的动画。
整体这部分的代码路径是在platform/bootable/recovery下,主要涉及的类是screen_ui.cpp
修改的思路是替换installationOverlay01-07.png图片为自己需要的图片,然后修改installationOverlay01-07.png显示的坐标位置,同时调整一下下方progressbar的高度和文字的高度,实现整体协调的效果。
修改installationOverlay01-07.png的具体位置:
void ScreenRecoveryUI::draw_install_overlay_locked(int frame) { if (installationOverlay == NULL || overlay_offset_x < 0) return; gr_surface surface = installationOverlay[frame]; int iconWidth = gr_get_width(surface); int iconHeight = gr_get_height(surface); // 改变iconX和iconY的位置,修改overlay图片的描画坐标,数值自己定 int iconX = (gr_fb_width()-127) / 2; int iconY = (gr_fb_height()-192) / 2; gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); }
修改progressbar的具体高度:
void ScreenRecoveryUI::draw_progress_locked() { if (currentIcon == ERROR) return; if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { draw_install_overlay_locked(installingFrame); } if (progressBarType != EMPTY) { int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); int width = gr_get_width(progressBarEmpty); int height = gr_get_height(progressBarEmpty); //修改dx dy的数值,改变progressbar的位置显示 int dx = (gr_fb_width() - width)/2; int dy = (3*gr_fb_height() + iconHeight - 2*height)/4; // Erase behind the progress bar (in case this was a progress-only update) gr_color(0, 0, 0, 255); gr_fill(dx, dy, width, height); if (progressBarType == DETERMINATE) { float p = progressScopeStart + progress * progressScopeSize; int pos = (int) (p * width); if (rtl_locale) { // Fill the progress bar from right to left. if (pos > 0) { gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); } if (pos < width-1) { gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); } } else { // Fill the progress bar from left to right. if (pos > 0) { gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); } if (pos < width-1) { gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); } } } if (progressBarType == INDETERMINATE) { static int frame = 0; gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); // in RTL locales, we run the animation backwards, which // makes the spinner spin the other way. if (rtl_locale) { frame = (frame + indeterminate_frames - 1) % indeterminate_frames; } else { frame = (frame + 1) % indeterminate_frames; } } } }
修改升级和恢复出厂界面下文字的位置:
void ScreenRecoveryUI::draw_background_locked(Icon icon) { pagesIdentical = false; gr_color(0, 0, 0, 255); gr_fill(0, 0, gr_fb_width(), gr_fb_height()); if (icon) { gr_surface surface = backgroundIcon[icon]; gr_surface text_surface = backgroundText[icon]; int iconWidth = gr_get_width(surface); int iconHeight = gr_get_height(surface); int textWidth = gr_get_width(text_surface); int textHeight = gr_get_height(text_surface); int iconX = (gr_fb_width() - iconWidth) / 2; int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; //这里改变文字的位置坐标,会同时影响恢复出厂设置和升级界面显示下的文字位置 int textX = (gr_fb_width() - textWidth) / 2; int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40; gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); if (icon == INSTALLING_UPDATE || icon == ERASING) { draw_install_overlay_locked(installingFrame); } gr_color(255, 255, 255, 255); gr_texticon(textX, textY, text_surface); } }
动画播放的频率默认是1秒钟20帧。如果修改可以在这里改:
void ScreenRecoveryUI::progress_loop() { double interval = 1.0 / animation_fps; ...... } }
遇到的坑主要有两个。
第一个就是在替换图片的时候,最开始替换的图片的位深度跟原始图片的位深度不一致,导致图片进去后花屏,后来查清楚了原来是图片位深度引起的,所以在替换图片的时候如果图片被不正常的拉伸了,可以看下是否是位深度不一样导致的。
第二个就是遇到了一个奇怪的现象,每次烧写之后如果直接升级的话,升级的界面显示总是跟自己改的不一样,但是如果烧写后恢复出厂的话,然后再次升级,则界面显示是完全ok的,这个问题也查了很久最终定位在recovery模式下的语言locale上,因为升级调用启动程序是自己写的,在往/cache/recovery/command写入升级命令的时候只写了--update_package命令,并没有给指定--locale=en_US或是--locale=zh_CN,所以recovery模式并未识别到语言环境,导致影响了screen_ui.cpp中关于textHeight的计算,而textHeight的数值又影响了图片以及文字的高度设置,所以看起来不会按照自己设置的方式来改变。
升级时的语言识别的逻辑是这样的:
首先进入recovery模式后,在执行Recovery.cpp的main函数时,会对/cache/recovery/command写入的命令进行逐行解析,当解析到locale的时候,就会将当前升级操作的locale设置为读到的内容,当没有在command中读到locale的时候,系统会走load_locale_from_cache()函数,来获取上一次我们是否在/cache/recovery/last_locale中写入了之前的语言环境,如果还是没有的话,locale就真的找不到了,text的高度是根据locale来获取的,这时候就会影响text的高度的值,从而导致升级界面出现问题。
那为什么先恢复出厂设置后再升级就没问题了呢?原因是恢复出厂设置的最后一步会在/cache/recovery/last_locale中写入语言环境,这样在下次升级的时候就可以找到一个语言的依据,也就不会导致text高度出现问题。
int main(int argc, char **argv) { ...... int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': just_exit = true; break; case 'l': locale = optarg; break; case 'g': { if (stage == NULL || *stage == '\0') { char buffer[20] = "1/"; strncat(buffer, optarg, sizeof(buffer)-3); stage = strdup(buffer); } break; } case '?': LOGE("Invalid command argument\n"); continue; } } if (locale == NULL) { load_locale_from_cache(); } ...... }
static void load_locale_from_cache() { // LOCALE_FILE就是/cache/recovery/last_locale FILE* fp = fopen_path(LOCALE_FILE, "r"); char buffer[80]; if (fp != NULL) { fgets(buffer, sizeof(buffer), fp); int j = 0; unsigned int i; for (i = 0; i < sizeof(buffer) && buffer[i]; ++i) { if (!isspace(buffer[i])) { buffer[j++] = buffer[i]; } } buffer[j] = 0; locale = strdup(buffer); check_and_fclose(fp, LOCALE_FILE); } }
刚开始接触底层,有些可能说的不对,希望自己对底层一点点的熟悉起来。对于这部分的代码可以通过LOGI来进行log输出,然后在恢复出厂后在/cache/recovery/last_log中查看到自己打印的log信息。
另外看了下android 7.1的这部分的代码,发现貌似已经可以利用max_stage是否为-1来控制不显示图片,只显示文字了。
最后附上两个博客,对了解recovery模式和recovery模式的界面描画很有帮助。
http://blog.csdn.net/u010223349/article/details/40392789 http://blog.csdn.net/fengying765/article/details/38301895
相关文章推荐
- android恢复出厂设置以及系统升级流程
- android恢复出厂设置以及系统升级流程
- Android 恢复出厂设置(系统时间不修改)
- android恢复出厂设置以及系统升级流程
- android恢复出厂设置以及系统升级流程
- android恢复出厂设置以及系统升级流程
- 路由器的恢复出厂设置、修改特权密码、备份配置文件和升级操作系统实际操作
- Android中 跳转到系统设置界面方法总结
- 调试路由器----恢复出厂设置、修改特权密码、备份配置文件、升级操作系统
- Android跳转到手机系统各个设置界面的方法及其列表
- Android 8.0接收通知后会手机崩溃,闪屏,恢复出厂设置的解决方法
- 如何旋转recovery界面:恢复出厂设置界面和Fota升级界面
- Android 如何才能捕获系统的恢复出厂设置事件
- Android 如何才能捕获系统的恢复出厂设置事件
- android高通平台调用恢复出厂设置的方法
- Android跳转到系统各个设置界面的方法及其列表
- Android 如何才能捕获系统的恢复出厂设置事件
- Android 如何才能捕获系统的恢复出厂设置事件
- Android 如何才能捕获系统的恢复出厂设置事件
- Android 如何才能捕获系统的恢复出厂设置事件