时人不识凌云木,直待凌云始道高。这篇文章主要讲述Android recover文字显示相关的知识,希望能为你提供帮助。
参考:
Recovery模式下的文本显示
如何修改Recovery的字符串资源
Android recovery UI实现分析
Recovery模式下的文本显示
平台 | android版本 | 内核版本 |
---|---|---|
rtd1619 | 9.0 | 4.9.1 |
需求:
选择简体中文的情况下,但在ota升级界面文字显示为 繁体。需要调整回来思路:
1.recovery 所匹配的文字并非是根据语言国家来更改res/xml下的文本文件,而是一个包含各种语言的文本图片 (bootable/recovery/res-hdpi/images/installing_text.png)
文章图片
2.在制作该文本png图片时候,会记录每种语言每段的信息,(locale,high,width)locale即(语言-国家)的信息
3.在进行recovery 时候,会传入android 环境下的locale ,如果传入的locale和解析png图片的locale相匹配这将这段绘制到surface
- UI加载入口
recover 和bootcode一样是一个简单的rootfs.使用surface直接刷framebuffer 更改界面,先查看 recovery.cpp 的main入口
int main(int argc, char **argv) {
// We don\'t have logcat yet under recovery;
so we\'ll print error on screen and
// log to stdout (which is redirected to recovery.log) as we used to do.
android::base::InitLogging(argv, &
UiLogger);
...
...
...
while ((arg = getopt_long(args_to_parse.size(), args_to_parse.data(), "", OPTIONS,
&
option_index)) != -1) {...
case \'l\':
locale = optarg;
//从参数中获取local “语言+国家”的形式
}
}
locale就是我们本文的关键
Device* device = make_device();
if (android::base::GetBoolProperty("ro.boot.quiescent", false)) {
printf("Quiescent recovery mode.\\n");
ui = new StubRecoveryUI();
} else {
ui = device->
GetUI();
if (!ui->
Init(locale)) {
printf("Failed to initialize UI, use stub UI instead.\\n");
ui = new StubRecoveryUI();
}
...
// Set background string to "installing security update" for security update,
// otherwise set it to "installing system update".
ui->
SetSystemUpdateText(security_update);
//设置是否为安全更新
}
这里又将locale 传入UI对象
- UI对象查找png文件
源文件 screen_ui.cpp
bool ScreenRecoveryUI::Init(const std::string&
locale) {
RecoveryUI::Init(locale);
...
LoadBitmap("icon_error", &
error_icon);
LoadBitmap("progress_empty", &
progressBarEmpty);
LoadBitmap("progress_fill", &
progressBarFill);
LoadBitmap("stage_empty", &
stageMarkerEmpty);
LoadBitmap("stage_fill", &
stageMarkerFill);
installing_text = nullptr;
//这个即我所需要的
LoadLocalizedBitmap("erasing_text", &
erasing_text);
LoadLocalizedBitmap("no_command_text", &
no_command_text);
LoadLocalizedBitmap("error_text", &
error_text);
...
}
...
// Choose the right background string to display during update.
void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
if (security_update) {
LoadLocalizedBitmap("installing_security_text", &
installing_text);
} else {
LoadLocalizedBitmap("installing_text", &
installing_text);
//加载图片
}
Redraw();
}
...
void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) {
int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface);
}
- 加载,分析png图片所需要的段
nt res_create_localized_alpha_surface(const char* name,
const char* locale,
GRSurface** pSurface) {
...
printf(" create surface by native locale area %s\\n", locale);
PngHandler png_handler(name);
// 根据installing_text名字加载png
if (!png_handler) return png_handler.error_code();
if (png_handler.channels() != 1) {
return -7;
}png_structp png_ptr = png_handler.png_ptr();
//获取png每段的信息
png_uint_32 width = png_handler.width();
png_uint_32 height = png_handler.height();
for (png_uint_32 y = 0;
y <
height;
++y) {
std::vector<
unsigned char>
row(width);
png_read_row(png_ptr, row.data(), nullptr);
int w = (row[1] <
<
8) | row[0];
int h = (row[3] <
<
8) | row[2];
__unused int len = row[4];
char* loc = reinterpret_cast<
char*>
(&
row[5]);
//在png格式中第五段是locale信息(语言_国家)
printf(" create surface name %20s\\n", name);
//自己加的log信息
printf(" create surface locale %s\\n", locale);
printf(" create surface loc %s\\n", loc);
//matches_locale()即用来匹配传入的locale 信息
if (y + 1 + h >
= height || matches_locale(loc, locale)) {
printf("res_create_localized_alpha_surface%20s: %s (%d x %d @ %d)\\n", name, loc, w, h, y);
GRSurface* surface = malloc_surface(w * h);
if (!surface) {
return -8;
}
//加载符合的数据到surface
surface->
width = w;
surface->
height = h;
surface->
row_bytes = w;
surface->
pixel_bytes = 1;
for (int i = 0;
i <
h;
++i, ++y) {
png_read_row(png_ptr, row.data(), nullptr);
memcpy(surface->
data + i * w, row.data(), w);
}*pSurface = surface;
break;
}for (int i = 0;
i <
h;
++i, ++y) {
png_read_row(png_ptr, row.data(), nullptr);
}
}return 0;
}
这里需要看自身的log信息看png的locale信息
比如这里我的设置中文简体情况为:
png locale: zh_CN
传入的 locale:zh-CN
这里有个问题就是:在解析台湾字段时段为
png locale :zh //看备注
所以直接匹配到了繁体
所以我们需要更改匹配规则
- 如何比较locale信息
index 52ab60b..b5cc62f 100644
--- a/minui/resources.cpp
+++ b/minui/resources.cpp
@@ -397,15 +397,22 @@ bool matches_locale(const std::string&
prefix, const std::string&
locale) {
// match the locale string without the {script} section.
// For instance, prefix == "en" matches locale == "en-US", prefix == "sr-Latn" matches locale
// == "sr-Latn-BA", and prefix == "zh-CN" matches locale == "zh-Hans-CN".
+// prefix == "zh_CN" matches locale == "zh-Hans-CN".
if (android::base::StartsWith(locale, prefix)) {
return true;
}
-size_t separator = prefix.find(\'-\');
+size_t separator = prefix.find(\'_\');
if (separator == std::string::npos) {
+
return false;
}
-std::regex loc_regex(prefix.substr(0, separator) + "-[A-Za-z]*" + prefix.substr(separator));
+if( prefix.substr(separator+1).empty()){
+return false;
+}+std::regex loc_regex(prefix.substr(0, separator) + "-[A-Za-z]*" + prefix.substr(separator+1));
return std::regex_match(locale, loc_regex);
}
- 以上就是修改内容
- 如何自己生成png图片
在android 下面已经有源码 直接生成apk,再有apk生成png
具体操作可以看
【Android recover文字显示】https://www.cnblogs.com/jianggest/p/recovery_string.html
- c++ 的std::regex 类需要学习
- png 数据分析 需要学习
PngHandler::PngHandler(const std::string&
name) : error_code_(0), png_fp_(nullptr, fclose) {
std::string res_path = android::base::StringPrintf("/res/images/%s.png", name.c_str());
png_fp_.reset(fopen(res_path.c_str(), "rbe"));
if (!png_fp_) {
error_code_ = -1;
return;
}unsigned char header[8];
size_t bytesRead = fread(header, 1, sizeof(header), png_fp_.get());
if (bytesRead != sizeof(header)) {
error_code_ = -2;
return;
}if (png_sig_cmp(header, 0, sizeof(header))) {
error_code_ = -3;
return;
}png_ptr_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png_ptr_) {
error_code_ = -4;
return;
}info_ptr_ = png_create_info_struct(png_ptr_);
if (!info_ptr_) {
error_code_ = -5;
return;
}if (setjmp(png_jmpbuf(png_ptr_))) {
error_code_ = -6;
return;
}png_init_io(png_ptr_, png_fp_.get());
png_set_sig_bytes(png_ptr_, sizeof(header));
png_read_info(png_ptr_, info_ptr_);
int color_type;
int bit_depth;
png_get_IHDR(png_ptr_, info_ptr_, &
width_, &
height_, &
bit_depth, &
color_type, nullptr, nullptr,
nullptr);
channels_ = png_get_channels(png_ptr_, info_ptr_);
if (bit_depth == 8 &
&
channels_ == 3 &
&
color_type == PNG_COLOR_TYPE_RGB) {
// 8-bit RGB images: great, nothing to do.
} else if (bit_depth <
= 8 &
&
channels_ == 1 &
&
color_type == PNG_COLOR_TYPE_GRAY) {
// 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray.
png_set_expand_gray_1_2_4_to_8(png_ptr_);
} else if (bit_depth <
= 8 &
&
channels_ == 1 &
&
color_type == PNG_COLOR_TYPE_PALETTE) {
// paletted images: expand to 8-bit RGB.Note that we DON\'T
// currently expand the tRNS chunk (if any) to an alpha
// channel, because minui doesn\'t support alpha channels in
// general.
png_set_palette_to_rgb(png_ptr_);
channels_ = 3;
} else {
fprintf(stderr, "minui doesn\'t support PNG depth %d channels %d color_type %d\\n", bit_depth,
channels_, color_type);
error_code_ = -7;
}
}
推荐阅读
- Android7.0以上通知的解决办法
- uni-app开发微信小程序(微信获取地址接受数据时出现错误)
- mapstruct 实体转换及List转换,@Mapper注解转换
- android开发全屏切换代码,记录一下
- android检测心率应用实例
- IfcRepresentationMap—Mapped shape without transformation
- Instant Apps调研
- APP测试的测试点
- tk.mybatis.mapper.MapperException: 当前实体类不包含名为的属性!,500错误