16 мая 2013 г.

Индикатор батареи на Android устройствах

По умолчанию устройства на ОС Android отображают заряд батареи набором простых пиктограмм, по которым сложно определить точный процент. Существует даже ряд специальных программ, выводящих в строку состояния точную цифру. Но в них нет необходимости, если приложить немного brains.dll и pryamie_ruki.sys: ведь в системе уже есть практически всё, что нужно!
Способ работает для любых устройств (может быть, кроме самых экзотичных).

Нам понадобится:
  1. JDK
  2. Файл framework-res.apk с Android устройства (находится в папке /system/framework)
  3. Рут на устройстве либо ClockworkMod recovery либо любой другой способ записи в /system/framework
  4. Утилиты отсюда
  5. Иконки батареи с процентами. Я приведу инструкцию для отображения процентов с шагом в единицу, т.е. иконок должно быть 100 для штатной работы батареи, ~5-10 для зарядки и 1 на случай неизвестного состояния. По желанию инструкция легко модифицируется для любого произвольного шага (например, если иконки получаются тяжеловесными, можно сделать шаг в 5%, чтобы не слишком раздувать итоговый файл framework). Поиск иконок выходит за рамки этой статьи, могу разве что посоветовать воспользоваться Кухней — там есть достаточное количество неплохих наборов.

Приступим

  1. Скачайте файл /system/framework/framework-res.apk с Android устройства на компьютер.
  2. Скачайте и распакуйте Android_APKTools туда же.
  3. Откройте командную строку и перейдите в папку с framework-res.apk и утилитами.
  4. Выполните команду
    java -jar apktool.jar d -s -f framework-res.apk
    . Если всё благополучно, вы увидите следующие строки:
    I: Loading resource table...
    I: Loaded.
    I: Decoding file-resources...
    I: Decoding values*/* XMLs...
    I: Done.
    I: Copying assets and libs...
    а в папке \framework-res появятся файлы разобранного фреймворка.
  5. Скачайте следующие иконки батареи:
    * stat_sys_battery_{#}.png, где {#} - числа от 0 до 100. Если будет искушение добавить ведущие нули — не поддавайтесь. Это прибавит проблем в дальнейшем.
    * stat_sys_battery_charge_anim{#}.png, где {#} - числа от 0 до 5-10. Эти файлы отвечают за анимацию батареи в процессе зарядки, поэтому сильной детализации не требуется. Вполне можно обойтись и пятью. Тем более что от шага аимации зарядки зависит сложность дальнейшей модификации. Для облегчения процесса можно посмотреть, какие файлы анимации зарядки имеются в исходном framework, и просто заменить их, не добавляя новых.
    * stat_sys_battery_unknown.png
    и поместите их в \framework-res\res\drawable-*dpi — папку, из которой берётся графика для DPI вашего устройства. Для смартфонов это обычно hdpi, для Nook Simple Touch — mdpi. Определяется изучением характеристик устройства либо тупым перебором :)
  6. Откройте файл \framework-res\res\drawable\stat_sys_battery.xml в текстовом редакторе. Каждая строка вида
    <item android:drawable="@drawable/stat_sys_battery_#...
    отвечает за иконку батареи. Как видно, их крайне немного. Будем менять эту ситуацию. Выделите все строки такого вида и удалите их, после чего вставьте строки со своим шагом процентов по следующему шаблону:
    <item android:drawable="@drawable/stat_sys_battery_{#}" android:maxLevel="{#}" />
    где вместо {#} - числа от 0 до 100. Фрагменты stat_sys_battery_{#} должны в точности соответствовать именам файлов \framework-res\res\drawable-*dpi\stat_sys_battery_{#}.png! Сохраните xml.
  7. Если вы заменили иконки анимации зарядки, не добавляя новых и не удаляя старых, пропустите этот шаг.
    Откройте файл \framework-res\res\drawable\stat_sys_battery_charge.xml в текстовом редакторе. Он уже устроен посложнее. За каждый кадр зарядки отвечает блок вида
    
            
                
                
            
        
    
    где {PERCENT} — % заряда батареи, вплоть до которого будет показываться данная анимация (maxLevel="5" означает, что данная анимация показывается при уровне заряда от 0% до 5%);
    {#FROM} — номер первого кадра анимации
    {#TO} — номер второго кадра анимации.
    Обычно {#TO} = {#FROM} + 1, т.е. кадры просто идут один за другим по порядку. Первый кадр следующего блока совпадает со вторым кадром предыдущего.
    Последним блоком должен идти завершающий:
    Сохраните xml.
  8. В командной строке выполните
    java -jar apktool.jar b -f framework-res
    . Если всё удачно, появятся следующие строки:
    W: Could not find sources
    I: Building resources...
    I: Building apk file...
    и в папке framework-res\build\apk появятся скомпилированные файлы APK. Оттуда нам нужны файл(ы) xml, которые мы изменяли.
  9. Открываем framework-res.apk в WinRAR или любом другом архиваторе и добавляем файлы:
    В res\drawable-*dpi — все *.png с новыми иконками батареи, уровень сжатия - без сжатия (Важно!)
    В res\drawable — framework-res\build\apk\drawable\stat_sys_battery.xml и framework-res\build\apk\res\drawable\stat_sys_battery_charge.xml (только если меняли его), уровень сжатия — обычный.
    В корень — framework-res\build\apk\resources.arsc, уровень сжатия — без сжатия.
    Прим. Это тонкий, но крайне важный момент. Поскольку мы добавляли графику в пакет, при сборке новые файлы получили новые идентификаторы. В разобранном виде они хранятся в файле values\public.xml (можете убедиться, разобрав framework-res\build\dist\framework-res.apk), а в собранном входят в состав файла-контейнера resources.arsc.
  10. Записываем итоговый framework-res.apk обратно на Android устройство. Здесь надо заметить, что файл этот — самый что ни есть системный, и его «горячая» замена может натворить немало бед (у меня, к примеру, несколько раз слетал гуглоаккаунт). Поэтому безопаснее всего заменять файл из режима recovery: через update zip либо посредством adb. Вот три команды, которые помогут в этом (поскольку в режиме рекавери разделы обычно не подключены, их надо подключать вручную. Наверняка можно это как-то сделать через шелл, но у меня не было желания разбираться, к тому же в ClockworkMod recovery есть опция "Mount /system").
    adb reboot recovery
    :: Ждем, пока девайс загрузится в рекавери и подключаем /system вручную
    adb push framework-res.apk /system/framework/framework-res.apk
    adb reboot
    
  11. Если всё сделано правильно — радуемся циферкам на батарее :) В противном случае чешем репу, смотрим логи, восстанавливаемся из бэкапа, который, конечно же, предварительно сделали :)

Комментариев нет:

Отправить комментарий