Как изменить системное приложение на андроид

Замена компонентов Android с использованием только диспетчера файлов с правами root.

Как заменять системные APK-файлы на Android?

Это опять я и мои инструкции для чайников и кофейников с картинками.

На этот раз я подробно расскажу о замене системных компонентов ОС Android на примере установки модификации строки состояния.

Android — это маленький Linux. В нём надо соблюдать ряд правил при замене файлов, чтобы телефон не превратился в кирпич, оживить который поможет только полная перепрошивка с потерей всех данных из внутренней памяти устройства. Внутренние разделы отформатированы в файловую систему отличную от FAT32 на флешках. В свойствах файла кроме всего прочего хранятся разрешения для разных групп пользователей (хозяин файла, группа хозяина файла, остальные пользователи). При операции с системными файлами их надо сохранять, потому что при загрузке система просто может не суметь получить к ним доступ и не загрузиться нормально.
Начнем с инструментария.

Нам понадобится:

  • Менеджер файлов, который умеет работать с root-правами и разрешениями файлов. Лучше всего подойдет Root Explorer (Вы же его купили, да?)
  • Сам модифицированный файл, который мы хотим положить наместо системного (ссылка в конце статьи).

Для начала нужно найти и сохранить резервную копию заменяемого файла.
Для этого запускаем Root Explorer и переходим в каталог «/system/app» и в списке находим нужный файл.

Теперь используем одну из удобных функций Root Explorer. Сделаем долгий тап по нужному файлу, чтобы вызвать контекстное меню

И щелкаем по пункту «Zip this file«, чтобы сохранить файл в zip-архиве на SD-карте. После архивации получим такое сообщение:

Нажимаем кнопкй «Stay«, чтобы остаться в папке и сделать еще кое-что.

Теперь всё готово для замены файла.
Я уже говорил про права доступа у каждого файла. Чтобы их воссоздать на новом файле, надо сначала посмотреть их у старого. Они представлены рядом символов «rwxrwxrwx«. 1-я триада — права владельца, 2-я — группы владельца, 3-я — всех остальных пользователей. У нашего файла права «rw-r—r—«.

Теперь переходим на SD-карту, находим там модифицированный файл и из его контекстного меню выбираем пункт «Copy«, но не торопимся выбирать сразу папку «/system/app«, потому что мы тут же повредим систему. Вместо этого копируем файл в специальную папку для временных файлов «/data/local/tmp«, чтобы привести файл в вид, который примет система.
Для начала вызовем контекстное меню файла и выберем пункт «Rename» и введем имя файла «SystemUI.apk«. Именно так, потому что в Linux регистр букв в имени имеет значение, т.е. «systemui.apk» и «SystemUI.apk» — это разные файлы.
Далее надо изменить права на файл, потому что сейчас они почти наверняка выставлены неправильно. Для этого опять вызываем контекстное меню файла долгим тапом и выбираем пункт «Permissions«. Для нашего значени «rw-r—r—» флажки надо расставить так:

Нажимаем «OK» и снова вызываем контекстное меню. Теперь надо изменить владельца и группу для этого приложения. Для этого выбираем пункт «Изменить владельца«. Появится окно с информацией о текущем владельце файла.
Тут надо сделать маленькое отступление.
В папке «/system/app» всеми файлами владеет пользователь «root» (uid=0) и группа «root» (gid=0), а в папке «/system/framework» властвует пользователь «system» (gid=1000) и группа «system» (gid=1000).
Исходя из вышесказанного, выставляем нужные значения и нажимаем «OK«.
И в третий раз вызываем контекстное меню для файла и в нем выбираем пункт «Copy» и в диалоге копирования переходим в папку «/system/app«. Теперь смело нажимаем «Paste» и читаем дальше внимательно.
Практически сразу система сообщит, что процесс строки состояния внезапно завершился, и предложит его запустить. Всё попытки будут неудачными. Между появлениями окон надо успеть сделать ряд действий. Перед нажатием кнопки надо вызвать меню выключения аппарата, оно окажется под предупреждением. Теперь надо расположить палец примерно в левой стороне кнопки. Теперь надо очень быстро щелкнуть три раза пальцем, что успеть закрыть предупреждение, выбрать пункт выключения и подтвердить свои намерения.
Теперь ждем выключения телефона, заново его запускаем и наслаждаемся результатом или не наслаждаемся и ищем ошибки.

И обещанный архив с модифицированным файлом. http://radjah.ucoz.ru/rar/systemui.zip (324 килобайт)

Товарищ Sashoooq подсказал более безопасный вариант установки подобных модификаций.После копирования файла в «/data/local/tmp» и изменения прав у него скопировать его в папку «/system/framework» и перезагрузить телефон. В итоге оригинальный файл останется лежать на своём месте, а система будет загружать модифицированный.Такой способ не является безопасным для apk-файлов, которые уже лежат в этой папке. А лежат там очень вайжные для работы и стабильности системы файлы («framework-res.apk» и некоторые файлы от производителя).

Статься написана специально для форума 4PDA.

—>

Можно ли заменить стандартное приложение галереи на стороннее и как это сделать? P. S. CM 11, рут есть, рекавери есть.

Последнее изменение: 20 сентября 2016, 21:40

justmax437

justmax437, 10 октября 2014, 20:40   #   (…)

Ну удали системное и поставь сторонее. В чем проблема?

Ответить

MichaelKorablin

MichaelKorablin, 10 октября 2014, 20:41   #   (…)

Система не будет ломаться когда будет пытаться перейти в галерею?

Ответить

justmax437

justmax437, 10 октября 2014, 21:59   #   (…)

Если ничего системно-критичного не удалишь — все будет ок

Ответить

kotik_S

kotik_S, 10 октября 2014, 20:40   #   (…)

Можно.Какое устройство?

Ответить

MichaelKorablin

MichaelKorablin, 10 октября 2014, 20:41   #   (…)

SGS3 4G

Ответить

kotik_S

kotik_S, 10 октября 2014, 20:45   #   (…)

у меня с3 мини, тогда будет тебе просто

Ответить

kotik_S

kotik_S, 10 октября 2014, 20:54   #   (…)

  • Сначала заходим в настройки
  • Затем выбираем там «Диспетчер приложений»:

__TCAPT__

  • Потом ищем там «Галерею» и заходим в неё:

__TCAPT__

  • Нажимаем «Отключить» и устанавливаем стороннюю галерею.

Ответить

Yack

Yack, 10 октября 2014, 20:41   #   (…)

speed8

speed8, 10 октября 2014, 21:30   #   (…)

Удали галерею через SD Maid или Clean Master, и поставь например QickPic как у меня.

Ответить

Arturmomo

Arturmomo, 10 октября 2014, 22:02   #   (…)

Низачто не удаляй системную галерею!
Если удалишь сис. галерею, то тап по маленькому окошку с последним списком не будет функционировать, а обои для экрана блокировки сменить будет нельзя(последнее зависит от v. Андроида)

Ответить

Mr-Strange

Mr-Strange, 20 сентября 2016, 20:30   #   (…)

Просто через Файловый менеджер с поддержкой Рута зайди в директорию (папку) /system/priv-app или /system/app и удали там Gallery.apk (или похожие на него).
Потом установи прогу на которую ты хочешь заменить галерею, поищи её в /data/app и скопируй в /system/app.

Ответить

Добавить комментарий

Если нужно ответить кому-то конкретно,
лучше нажать на «Ответить» под его комментарием

February 13 2012, 22:41

Categories:

  • IT
  • Техника
  • Cancel

Это опять я и мои инструкции для чайников и кофейников с картинками.
На этот раз я подробно расскажу о правильной замене системных компонентов ОС Android на примере установки модификации строки состояния.
Android — это маленький Linux. В нём надо соблюдать ряд правил при замене файлов, чтобы телефон не превратился в кирпич, оживить который поможет только полная перепрошивка с потерей всех данных из внутренней памяти устройства. Внутренние разделы отформатированы в файловую систему отличную от FAT32 на флешках. В свойствах файла кроме всего прочего хранятся разрешения для разных групп пользователей (хозяин файла, группа хозяина файла, остальные пользователи). При операции с системными файлами их надо сохранять, потому что при загрузке система просто может не суметь получить к ним доступ и не загрузиться нормально.
Начнем с инструментария.

Нам понадобится:

  • Менеджер файлов, который умеет работать с root-правами и разрешениями файлов. Лучше всего подойдет Root Explorer (Вы же его купили, да?)
  • Сам модифицированный файл, который мы хотим положить наместо системного (ссылка в конце статьи).

Для начала нужно найти и сохранить резервную копию заменяемого файла.
Для этого запускаем Root Explorer и переходим в каталог «/system/app» и в списке находим нужный файл.

Теперь используем одну из удобных функций Root Explorer. Сделаем долгий тап по нужному файлу, чтобы вызвать контекстное меню

И щелкаем по пункту «Zip this file«, чтобы сохранить файл в zip-архиве на SD-карте. После архивации получим такое сообщение:

Нажимаем кнопкй «Stay«, чтобы остаться в папке и сделать еще кое-что.

Теперь всё готово для замены файла.
Я уже говорил про права доступа у каждого файла. Чтобы их воссоздать на новом файле, надо сначала посмотреть их у старого. Они представлены рядом символов «

rwxrwxrwx«. 1-я триада — права владельца, 2-я — группы владельца, 3-я — всех остальных пользователей. У нашего файла права «rw-r—r—«.

Теперь переходим на SD-карту, находим там модифицированный файл и из его контекстного меню выбираем пункт «Copy«, но не торопимся выбирать сразу папку «

/system/app«, потому что мы тут же повредим систему. Вместо этого копируем файл в специальную папку для временных файлов «/data/local/tmp«, чтобы привести файл в вид, который примет система.
Для начала вызовем контекстное меню файла и выберем пункт «Rename» и введем имя файла «SystemUI.apk«. Именно так, потому что в Linux регистр букв в имени имеет значение, т.е. «systemui.apk» и «SystemUI.apk» — это разные файлы.
Далее надо изменить права на файл, потому что сейчас они почти наверняка выставлены неправильно. Для этого опять вызываем контекстное меню файла долгим тапом и выбираем пункт «Permissions«. Для нашего значени «rw-r—r—» флажки надо расставить так:

Нажимаем «OK» и снова вызываем контекстное меню. В нем выбираем пункт «Copy» и в диалоге копирования переходим в папку «

/system/app«. Теперь смело нажимаем «Paste» и читаем дальше внимательно.
Практически сразу система сообщит, что процесс строки состояния внезапно завершился, и предложит его запустить. Всё попытки будут неудачными. Между появлениями окон надо успеть сделать ряд действий. Перед нажатием кнопки надо вызвать меню выключения аппарата, оно окажется под предупреждением. Теперь надо расположить палец примерно в левой стороне кнопки. Теперь надо очень быстро щелкнуть три раза пальцем, что успеть закрыть предупреждение, выбрать пункт выключения и подтвердить свои намерения.
Теперь ждем выключения телефона, заново его запускаем и наслаждаемся результатом или не наслаждаемся и ищем ошибки.

И обещанный архив с модифицированным файлом. http://radjah.ucoz.ru/rar/systemui.zip (324 килобайт)

Статься написана специально для форума 4PDA.

Читать запись в блоге «Заметки дядюшки Раджи»

Добрый день!
Хочу поделиться с вами историей как я модифицировал одно из системных приложений Adroid’а, точнее его модификации LeWa OS. С Андроидом я познакомился недавно, всего месяц назад, и постараюсь тут описать весь ход своих мыслей, что несомненно будет полезно всем тем кто хочет улучшить Андроид, но не знает с чего начать. Пост постараюсь сделать подробным, а потому длинным.

Для начало немного истории.

Как только я получил свой первый китайфон, решил попробовать разные прошивки и в результате остановился на Lewa. Но глаза постоянно мозолил один ее недочет — список контактов, а точнее быстрая навигация на английском.

Информации о данной проблеме немного, поэтому начал копать сам.

Набор инструментов

Первое что нам надо — научиться распаковывать программы. Для этого нам понадобится:

  • установить Java
  • APKTOOLS для распаковки *.apk
  • Прочитать данный пост
  • Получить объект исследования. Если вы пользуетесь Lewa то надо из архива с прошивкой или прямо с телефона нужно вытянуть /system/app/PIM.apk и все apk из папки /system/framework/ обычно это framework-res.apk, lewa-res.apk и
    mediatek-res.apk. Если вы хотите просто потренироваться то могу дать свои

Приступим

Итак, первое что нам надо это разобрать наше приложение, для этого все apk надо скопировать в папку с apktools. Все apk которые лежали в /system/framework/ надо выделить, подцепить мышью и перенести на apktool-if.cmd тем самым открыв их с помощью этого bat’ника. PIM.apk таким же образом надо открыть с помощью apktool-d.cmd. В результате получаем папку с распакованным приложением.

Изучаем код

Первое что нам необходимо понять — что и где править. Так как мой список контактов изобилует русскими именами, а в быстротой навигации одни английские буквы резонно предположить, что буквы просто жестко забиты где то в коде, а не генерируются динамически исходя из того какие имена у вас в контактах. Обычно такие данные хранятся в папке res, а точнее в resvaluesarrays.xml но в нашем случае там ничего похожего нет.
Думаем дальше — раз нет там, значит есть где то в коде. Весь код находится в папе smali, по сути там не исходный код а так называемый Байт-код, и его там много. Так где же искать? Я поступил так, в папке reslayout хранятся все «окошки» нашего приложения, то что нам надо находится где-то в списке контактов, поэтому я наобум открыл contact_list_content.xml и начал изучать.

contact_list_content.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical" android:id="@id/pinned_header_list_layout" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <include android:id="@id/account_filter_header_container" layout="@layout/account_filter_header" />
    <include layout="@layout/wait_cursor" />
    <FrameLayout android:id="@id/contact_list_framelayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0">
        <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
            <view android:id="@android:id/list" android:fadingEdge="none" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:fastScrollEnabled="true" class="com.lewa.PIM.contacts.widget.PinnedHeaderListView" />
            <LinearLayout android:orientation="vertical" android:id="@id/import_layout" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="300.0dip" android:layout_marginBottom="@dimen/prompt_import_layout_bottom">
                <TextView android:textSize="16.0sp" android:gravity="center" android:layout_gravity="center_horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/prompt_no_contacts_pepole" />
                <Button android:textSize="14.0sp" android:gravity="center" android:layout_gravity="center_horizontal" android:id="@id/btn_login_lewa_account" android:layout_width="140.0dip" android:layout_height="wrap_content" android:layout_marginTop="18.0dip" android:text="@string/login_lewa_account" />
                <Button android:textSize="14.0sp" android:gravity="center" android:layout_gravity="center_horizontal" android:id="@id/btn_import_from_sim" android:layout_width="140.0dip" android:layout_height="wrap_content" android:layout_marginTop="18.0dip" android:text="@string/import_from_sim" />
                <Button android:textSize="14.0sp" android:gravity="center" android:layout_gravity="center_horizontal" android:id="@id/btn_import_from_sdcard" android:layout_width="140.0dip" android:layout_height="wrap_content" android:layout_marginTop="18.0dip" android:text="@string/import_from_sdcard" />
            </LinearLayout>
        </LinearLayout>
        <include layout="@layout/alphabet_fast_indexer" />
    </FrameLayout>
    <ViewStub android:id="@id/footer_stub" android:layout="@layout/footer_panel" android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>

Там меня заинтересовала строчка


<include layout="@layout/alphabet_fast_indexer" />

. Что это за индексер такой?? Смотрим

alphabet_fast_indexer.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView android:textSize="32.0sp" android:textColor="?android:textColorPrimaryInverse" android:gravity="center" android:layout_gravity="right|center" android:id="@id/fast_indexer_pop_text_view" android:background="@android:color/holo_blue_light" android:visibility="gone" android:layout_width="48.0dip" android:layout_height="48.0dip" android:layout_marginRight="60.0dip" />
    <com.lewa.PIM.widget.AlphabetFastIndexer android:layout_gravity="right" android:id="@id/fast_indexer" android:layout_width="20.0dip" android:layout_height="fill_parent" />
</FrameLayout>

Тут ключевые стороки
<com.lewa.PIM.widget.AlphabetFastIndexer android:layout_gravity=«right» android:id=»@id/fast_indexer» android:layout_width=«20.0dip» android:layout_height=«fill_parent» />
Что это за элемент который прижимается к правой части экрана (android:layout_gravity=«right»), не то ли что мы ищем?
com.lewa.PIM.widget.AlphabetFastIndexer это ссылка на код PIMsmalicomlewaPIMwidgetAlphabetFastIndexer.smali, но изучать его неудобно, и тут на сцену выходит связка dex2jar-0.0.9.7 jd-gui-0.3.3.windows которые мы скачали из поста на форуме и так же научились ими пользоваться. Превращаем classes.dex в classes_dex2jar.jar и открываем через jd-gui.exe

AlphabetFastIndexer.smali Декомпилированный

package com.lewa.PIM.widget;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;

public class AlphabetFastIndexer extends View
{
  public static String[] b = { "★", "#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
  private int choose = 0;
  private int mChooseColor;
  private boolean mHasFav = true;
  private ArrayList<String> mLetters = new ArrayList();
  private int mPaddingBottom;
  private int mTextsize;
  OnTouchingLetterChangedListener onTouchingLetterChangedListener;
  private Paint paint = new Paint();
  private boolean showBkg = false;

  public AlphabetFastIndexer(Context paramContext)
  {
    super(paramContext);
    init(paramContext);
    setHasFavorite(false);
  }

  public AlphabetFastIndexer(Context paramContext, AttributeSet paramAttributeSet)
  {
    super(paramContext, paramAttributeSet);
    init(paramContext);
    setHasFavorite(false);
  }

  public AlphabetFastIndexer(Context paramContext, AttributeSet paramAttributeSet, int paramInt)
  {
    super(paramContext, paramAttributeSet, paramInt);
    init(paramContext);
    setHasFavorite(false);
  }

  private void init(Context paramContext)
  {
    this.mChooseColor = paramContext.getResources().getColor(17170450);
    this.mTextsize = paramContext.getResources().getDimensionPixelSize(2131361937);
    this.mPaddingBottom = paramContext.getResources().getDimensionPixelSize(2131361938);
  }

  public boolean dispatchTouchEvent(MotionEvent paramMotionEvent)
  {
    int i = paramMotionEvent.getAction();
    int j = (int)(paramMotionEvent.getY() / getHeight() * this.mLetters.size());
    switch (i)
    {
    default:
      return true;
    case 0:
      this.showBkg = true;
    case 2:
      drawThumb(j);
      return true;
    case 1:
    }
    this.showBkg = false;
    invalidate();
    return true;
  }

  public void drawThumb(int paramInt)
  {
    OnTouchingLetterChangedListener localOnTouchingLetterChangedListener = this.onTouchingLetterChangedListener;
    if ((this.choose != paramInt) && (localOnTouchingLetterChangedListener != null) && (paramInt >= 0) && (paramInt < this.mLetters.size()))
    {
      if (localOnTouchingLetterChangedListener != null)
        localOnTouchingLetterChangedListener.onTouchingLetterChanged((String)this.mLetters.get(paramInt));
      this.choose = paramInt;
      invalidate();
    }
  }

  public void drawThumb(String paramString)
  {
    if ((paramString != null) && (!paramString.equals(this.mLetters.get(this.choose))))
    {
      int i = this.mLetters.indexOf(paramString);
      if (i == -1)
        i = 0;
      if (this.choose != i)
      {
        this.choose = i;
        invalidate();
      }
    }
  }

  protected void onDraw(Canvas paramCanvas)
  {
    super.onDraw(paramCanvas);
    if (this.showBkg)
      paramCanvas.drawColor(Color.parseColor("#4C000000"));
    while (true)
    {
      int i = getHeight();
      int j = getWidth();
      int k = this.mLetters.size();
      int m = i / k;
      for (int n = 0; n < k; n++)
      {
        this.paint.setColor(-1);
        this.paint.setTypeface(Typeface.DEFAULT_BOLD);
        this.paint.setAntiAlias(true);
        this.paint.setTextSize(this.mTextsize);
        if (n == this.choose)
        {
          this.paint.setColor(this.mChooseColor);
          this.paint.setFakeBoldText(true);
        }
        String str = (String)this.mLetters.get(n);
        paramCanvas.drawText(str, j / 2 - this.paint.measureText(str) / 2.0F, m + m * n, this.paint);
        this.paint.reset();
      }
      paramCanvas.drawColor(Color.parseColor("#26000000"));
    }
  }

  protected void onMeasure(int paramInt1, int paramInt2)
  {
    if (this.mHasFav)
      paramInt2 -= this.mPaddingBottom;
    setMeasuredDimension(paramInt1, paramInt2);
  }

  public boolean onTouchEvent(MotionEvent paramMotionEvent)
  {
    return super.onTouchEvent(paramMotionEvent);
  }

  public void setHasFavorite(boolean paramBoolean)
  {
    int k;
    if (this.mHasFav != paramBoolean)
    {
      this.mHasFav = paramBoolean;
      this.mLetters.clear();
      String[] arrayOfString = b;
      int i = arrayOfString.length;
      int j = 0;
      if (j < i)
      {
        String str = arrayOfString[j];
        if ((!paramBoolean) && (str.equals("★")));
        while (true)
        {
          j++;
          break;
          this.mLetters.add(str);
        }
      }
      if (this.choose != 0)
      {
        if (!paramBoolean)
          break label117;
        k = 1 + this.choose;
        this.choose = k;
      }
      if (this.choose >= 0)
        break label128;
      this.choose = 0;
    }
    while (true)
    {
      requestLayout();
      return;
      label117: k = -1 + this.choose;
      break;
      label128: if (this.choose >= this.mLetters.size())
        this.choose = (-1 + this.mLetters.size());
    }
  }

  public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener paramOnTouchingLetterChangedListener)
  {
    this.onTouchingLetterChangedListener = paramOnTouchingLetterChangedListener;
  }

  public static abstract interface OnTouchingLetterChangedListener
  {
    public abstract void onTouchingLetterChanged(String paramString);
  }
}

Вот же оно- public static String[] b = { «★», «#», «A», «B», «C», «D», «E», «F», «G», «H», «I», «J», «K», «L», «M», «N», «O», «P», «Q», «R», «S», «T», «U», «V», «W», «X», «Y», «Z» };!!! Но править прямо тут нельзя, декомпилированный код примерный, и врядли соберется обратно без ошибок, тем более у нас нет остальных частей программы. Так что правим байт код в PIMsmalicomlewaPIMwidgetAlphabetFastIndexer.smali

AlphabetFastIndexer.smali

.class public Lcom/lewa/PIM/widget/AlphabetFastIndexer;
.super Landroid/view/View;
.source "AlphabetFastIndexer.java"


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;
    }
.end annotation


# static fields
.field public static b:[Ljava/lang/String;


# instance fields
.field private choose:I

.field private mChooseColor:I

.field private mHasFav:Z

.field private mLetters:Ljava/util/ArrayList;
    .annotation system Ldalvik/annotation/Signature;
        value = {
            "Ljava/util/ArrayList",
            "<",
            "Ljava/lang/String;",
            ">;"
        }
    .end annotation
.end field

.field private mPaddingBottom:I

.field private mTextsize:I

.field onTouchingLetterChangedListener:Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;

.field private paint:Landroid/graphics/Paint;

.field private showBkg:Z


# direct methods
.method static constructor <clinit>()V
    .locals 3

    .prologue
    .line 19
    const/16 v0, 0x1c

    new-array v0, v0, [Ljava/lang/String;

    const/4 v1, 0x0

    const-string v2, "u2605"

    aput-object v2, v0, v1

    const/4 v1, 0x1

    const-string v2, "#"

    aput-object v2, v0, v1

    const/4 v1, 0x2

    const-string v2, "A"

    aput-object v2, v0, v1

    const/4 v1, 0x3

    const-string v2, "B"

    aput-object v2, v0, v1

    const/4 v1, 0x4

    const-string v2, "C"

    aput-object v2, v0, v1

    const/4 v1, 0x5

    const-string v2, "D"

    aput-object v2, v0, v1

    const/4 v1, 0x6

    const-string v2, "E"

    aput-object v2, v0, v1

    const/4 v1, 0x7

    const-string v2, "F"

    aput-object v2, v0, v1

    const/16 v1, 0x8

    const-string v2, "G"

    aput-object v2, v0, v1

    const/16 v1, 0x9

    const-string v2, "H"

    aput-object v2, v0, v1

    const/16 v1, 0xa

    const-string v2, "I"

    aput-object v2, v0, v1

    const/16 v1, 0xb

    const-string v2, "J"

    aput-object v2, v0, v1

    const/16 v1, 0xc

    const-string v2, "K"

    aput-object v2, v0, v1

    const/16 v1, 0xd

    const-string v2, "L"

    aput-object v2, v0, v1

    const/16 v1, 0xe

    const-string v2, "M"

    aput-object v2, v0, v1

    const/16 v1, 0xf

    const-string v2, "N"

    aput-object v2, v0, v1

    const/16 v1, 0x10

    const-string v2, "O"

    aput-object v2, v0, v1

    const/16 v1, 0x11

    const-string v2, "P"

    aput-object v2, v0, v1

    const/16 v1, 0x12

    const-string v2, "Q"

    aput-object v2, v0, v1

    const/16 v1, 0x13

    const-string v2, "R"

    aput-object v2, v0, v1

    const/16 v1, 0x14

    const-string v2, "S"

    aput-object v2, v0, v1

    const/16 v1, 0x15

    const-string v2, "T"

    aput-object v2, v0, v1

    const/16 v1, 0x16

    const-string v2, "U"

    aput-object v2, v0, v1

    const/16 v1, 0x17

    const-string v2, "V"

    aput-object v2, v0, v1

    const/16 v1, 0x18

    const-string v2, "W"

    aput-object v2, v0, v1

    const/16 v1, 0x19

    const-string v2, "X"

    aput-object v2, v0, v1

    const/16 v1, 0x1a

    const-string v2, "Y"

    aput-object v2, v0, v1

    const/16 v1, 0x1b

    const-string v2, "Z"

    aput-object v2, v0, v1

    sput-object v0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->b:[Ljava/lang/String;

    return-void
.end method

.method public constructor <init>(Landroid/content/Context;)V
    .locals 2
    .parameter "context"

    .prologue
    const/4 v1, 0x0

    .line 44
    invoke-direct {p0, p1}, Landroid/view/View;-><init>(Landroid/content/Context;)V

    .line 22
    iput v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 23
    new-instance v0, Landroid/graphics/Paint;

    invoke-direct {v0}, Landroid/graphics/Paint;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    .line 27
    const/4 v0, 0x1

    iput-boolean v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    .line 29
    new-instance v0, Ljava/util/ArrayList;

    invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    .line 112
    iput-boolean v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    .line 45
    invoke-direct {p0, p1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->init(Landroid/content/Context;)V

    .line 46
    invoke-virtual {p0, v1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->setHasFavorite(Z)V

    .line 47
    return-void
.end method

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
    .locals 2
    .parameter "context"
    .parameter "attrs"

    .prologue
    const/4 v1, 0x0

    .line 38
    invoke-direct {p0, p1, p2}, Landroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V

    .line 22
    iput v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 23
    new-instance v0, Landroid/graphics/Paint;

    invoke-direct {v0}, Landroid/graphics/Paint;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    .line 27
    const/4 v0, 0x1

    iput-boolean v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    .line 29
    new-instance v0, Ljava/util/ArrayList;

    invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    .line 112
    iput-boolean v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    .line 39
    invoke-direct {p0, p1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->init(Landroid/content/Context;)V

    .line 40
    invoke-virtual {p0, v1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->setHasFavorite(Z)V

    .line 41
    return-void
.end method

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
    .locals 2
    .parameter "context"
    .parameter "attrs"
    .parameter "defStyle"

    .prologue
    const/4 v1, 0x0

    .line 32
    invoke-direct {p0, p1, p2, p3}, Landroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V

    .line 22
    iput v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 23
    new-instance v0, Landroid/graphics/Paint;

    invoke-direct {v0}, Landroid/graphics/Paint;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    .line 27
    const/4 v0, 0x1

    iput-boolean v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    .line 29
    new-instance v0, Ljava/util/ArrayList;

    invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V

    iput-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    .line 112
    iput-boolean v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    .line 33
    invoke-direct {p0, p1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->init(Landroid/content/Context;)V

    .line 34
    invoke-virtual {p0, v1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->setHasFavorite(Z)V

    .line 35
    return-void
.end method

.method private init(Landroid/content/Context;)V
    .locals 2
    .parameter "context"

    .prologue
    .line 50
    invoke-virtual {p1}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v0

    const v1, 0x1060012

    invoke-virtual {v0, v1}, Landroid/content/res/Resources;->getColor(I)I

    move-result v0

    iput v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mChooseColor:I

    .line 51
    invoke-virtual {p1}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v0

    const v1, 0x7f0a0091

    invoke-virtual {v0, v1}, Landroid/content/res/Resources;->getDimensionPixelSize(I)I

    move-result v0

    iput v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mTextsize:I

    .line 52
    invoke-virtual {p1}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v0

    const v1, 0x7f0a0092

    invoke-virtual {v0, v1}, Landroid/content/res/Resources;->getDimensionPixelSize(I)I

    move-result v0

    iput v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mPaddingBottom:I

    .line 53
    return-void
.end method


# virtual methods
.method public dispatchTouchEvent(Landroid/view/MotionEvent;)Z
    .locals 6
    .parameter "event"

    .prologue
    const/4 v5, 0x1

    .line 116
    invoke-virtual {p1}, Landroid/view/MotionEvent;->getAction()I

    move-result v0

    .line 117
    .local v0, action:I
    invoke-virtual {p1}, Landroid/view/MotionEvent;->getY()F

    move-result v2

    .line 118
    .local v2, y:F
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->getHeight()I

    move-result v3

    int-to-float v3, v3

    div-float v3, v2, v3

    iget-object v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v4}, Ljava/util/ArrayList;->size()I

    move-result v4

    int-to-float v4, v4

    mul-float/2addr v3, v4

    float-to-int v1, v3

    .line 120
    .local v1, c:I
    packed-switch v0, :pswitch_data_0

    .line 143
    :goto_0
    return v5

    .line 122
    :pswitch_0
    iput-boolean v5, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    .line 135
    :pswitch_1
    invoke-virtual {p0, v1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->drawThumb(I)V

    goto :goto_0

    .line 138
    :pswitch_2
    const/4 v3, 0x0

    iput-boolean v3, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    .line 140
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->invalidate()V

    goto :goto_0

    .line 120
    :pswitch_data_0
    .packed-switch 0x0
        :pswitch_0
        :pswitch_2
        :pswitch_1
    .end packed-switch
.end method

.method public drawThumb(I)V
    .locals 2
    .parameter "position"

    .prologue
    .line 152
    iget-object v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->onTouchingLetterChangedListener:Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;

    .line 153
    .local v0, listener:Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;
    iget v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    if-eq v1, p1, :cond_1

    if-eqz v0, :cond_1

    .line 154
    if-ltz p1, :cond_1

    iget-object v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v1}, Ljava/util/ArrayList;->size()I

    move-result v1

    if-ge p1, v1, :cond_1

    .line 155
    if-eqz v0, :cond_0

    .line 156
    iget-object v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v1, p1}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v1

    check-cast v1, Ljava/lang/String;

    invoke-interface {v0, v1}, Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;->onTouchingLetterChanged(Ljava/lang/String;)V

    .line 158
    :cond_0
    iput p1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 159
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->invalidate()V

    .line 162
    :cond_1
    return-void
.end method

.method public drawThumb(Ljava/lang/String;)V
    .locals 3
    .parameter "letter"

    .prologue
    .line 165
    if-eqz p1, :cond_1

    iget-object v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    iget v2, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    invoke-virtual {v1, v2}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v1

    invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v1

    if-nez v1, :cond_1

    .line 166
    iget-object v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v1, p1}, Ljava/util/ArrayList;->indexOf(Ljava/lang/Object;)I

    move-result v0

    .line 167
    .local v0, i:I
    const/4 v1, -0x1

    if-ne v0, v1, :cond_0

    const/4 v0, 0x0

    .line 168
    :cond_0
    iget v1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    if-eq v1, v0, :cond_1

    .line 169
    iput v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 170
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->invalidate()V

    .line 173
    .end local v0           #i:I
    :cond_1
    return-void
.end method

.method protected onDraw(Landroid/graphics/Canvas;)V
    .locals 12
    .parameter "canvas"

    .prologue
    const/4 v11, 0x1

    .line 83
    invoke-super {p0, p1}, Landroid/view/View;->onDraw(Landroid/graphics/Canvas;)V

    .line 84
    iget-boolean v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->showBkg:Z

    if-eqz v8, :cond_1

    .line 85
    const-string v8, "#4C000000"

    invoke-static {v8}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I

    move-result v8

    invoke-virtual {p1, v8}, Landroid/graphics/Canvas;->drawColor(I)V

    .line 90
    :goto_0
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->getHeight()I

    move-result v0

    .line 91
    .local v0, height:I
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->getWidth()I

    move-result v5

    .line 92
    .local v5, width:I
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v8}, Ljava/util/ArrayList;->size()I

    move-result v4

    .line 93
    .local v4, size:I
    div-int v3, v0, v4

    .line 94
    .local v3, singleHeight:I
    const/4 v1, 0x0

    .local v1, i:I
    :goto_1
    if-ge v1, v4, :cond_2

    .line 95
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    const/4 v9, -0x1

    invoke-virtual {v8, v9}, Landroid/graphics/Paint;->setColor(I)V

    .line 96
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    sget-object v9, Landroid/graphics/Typeface;->DEFAULT_BOLD:Landroid/graphics/Typeface;

    invoke-virtual {v8, v9}, Landroid/graphics/Paint;->setTypeface(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;

    .line 97
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    invoke-virtual {v8, v11}, Landroid/graphics/Paint;->setAntiAlias(Z)V

    .line 98
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    iget v9, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mTextsize:I

    int-to-float v9, v9

    invoke-virtual {v8, v9}, Landroid/graphics/Paint;->setTextSize(F)V

    .line 99
    iget v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    if-ne v1, v8, :cond_0

    .line 100
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    iget v9, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mChooseColor:I

    invoke-virtual {v8, v9}, Landroid/graphics/Paint;->setColor(I)V

    .line 101
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    invoke-virtual {v8, v11}, Landroid/graphics/Paint;->setFakeBoldText(Z)V

    .line 103
    :cond_0
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v8, v1}, Ljava/util/ArrayList;->get(I)Ljava/lang/Object;

    move-result-object v2

    check-cast v2, Ljava/lang/String;

    .line 104
    .local v2, letterStr:Ljava/lang/String;
    div-int/lit8 v8, v5, 0x2

    int-to-float v8, v8

    iget-object v9, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    invoke-virtual {v9, v2}, Landroid/graphics/Paint;->measureText(Ljava/lang/String;)F

    move-result v9

    const/high16 v10, 0x4000

    div-float/2addr v9, v10

    sub-float v6, v8, v9

    .line 105
    .local v6, xPos:F
    mul-int v8, v3, v1

    add-int/2addr v8, v3

    int-to-float v7, v8

    .line 106
    .local v7, yPos:F
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    invoke-virtual {p1, v2, v6, v7, v8}, Landroid/graphics/Canvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V

    .line 107
    iget-object v8, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->paint:Landroid/graphics/Paint;

    invoke-virtual {v8}, Landroid/graphics/Paint;->reset()V

    .line 94
    add-int/lit8 v1, v1, 0x1

    goto :goto_1

    .line 87
    .end local v0           #height:I
    .end local v1           #i:I
    .end local v2           #letterStr:Ljava/lang/String;
    .end local v3           #singleHeight:I
    .end local v4           #size:I
    .end local v5           #width:I
    .end local v6           #xPos:F
    .end local v7           #yPos:F
    :cond_1
    const-string v8, "#26000000"

    invoke-static {v8}, Landroid/graphics/Color;->parseColor(Ljava/lang/String;)I

    move-result v8

    invoke-virtual {p1, v8}, Landroid/graphics/Canvas;->drawColor(I)V

    goto :goto_0

    .line 110
    .restart local v0       #height:I
    .restart local v1       #i:I
    .restart local v3       #singleHeight:I
    .restart local v4       #size:I
    .restart local v5       #width:I
    :cond_2
    return-void
.end method

.method protected onMeasure(II)V
    .locals 1
    .parameter "widthMeasureSpec"
    .parameter "heightMeasureSpec"

    .prologue
    .line 77
    iget-boolean v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    if-eqz v0, :cond_0

    iget v0, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mPaddingBottom:I

    sub-int/2addr p2, v0

    .end local p2
    :cond_0
    invoke-virtual {p0, p1, p2}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->setMeasuredDimension(II)V

    .line 78
    return-void
.end method

.method public onTouchEvent(Landroid/view/MotionEvent;)Z
    .locals 1
    .parameter "event"

    .prologue
    .line 148
    invoke-super {p0, p1}, Landroid/view/View;->onTouchEvent(Landroid/view/MotionEvent;)Z

    move-result v0

    return v0
.end method

.method public setHasFavorite(Z)V
    .locals 6
    .parameter "hasFav"

    .prologue
    .line 56
    iget-boolean v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    if-eq v4, p1, :cond_4

    .line 57
    iput-boolean p1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mHasFav:Z

    .line 58
    iget-object v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v4}, Ljava/util/ArrayList;->clear()V

    .line 59
    sget-object v0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->b:[Ljava/lang/String;

    .local v0, arr$:[Ljava/lang/String;
    array-length v2, v0

    .local v2, len$:I
    const/4 v1, 0x0

    .local v1, i$:I
    :goto_0
    if-ge v1, v2, :cond_1

    aget-object v3, v0, v1

    .line 60
    .local v3, letter:Ljava/lang/String;
    if-nez p1, :cond_0

    const-string v4, "u2605"

    invoke-virtual {v3, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v4

    if-eqz v4, :cond_0

    .line 59
    :goto_1
    add-int/lit8 v1, v1, 0x1

    goto :goto_0

    .line 62
    :cond_0
    iget-object v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v4, v3}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z

    goto :goto_1

    .line 64
    .end local v3           #letter:Ljava/lang/String;
    :cond_1
    iget v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    if-eqz v4, :cond_2

    if-eqz p1, :cond_5

    iget v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    add-int/lit8 v4, v4, 0x1

    :goto_2
    iput v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 65
    :cond_2
    iget v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    if-gez v4, :cond_6

    const/4 v4, 0x0

    iput v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    .line 68
    :cond_3
    :goto_3
    invoke-virtual {p0}, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->requestLayout()V

    .line 70
    .end local v0           #arr$:[Ljava/lang/String;
    .end local v1           #i$:I
    .end local v2           #len$:I
    :cond_4
    return-void

    .line 64
    .restart local v0       #arr$:[Ljava/lang/String;
    .restart local v1       #i$:I
    .restart local v2       #len$:I
    :cond_5
    iget v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    add-int/lit8 v4, v4, -0x1

    goto :goto_2

    .line 66
    :cond_6
    iget v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    iget-object v5, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v5}, Ljava/util/ArrayList;->size()I

    move-result v5

    if-lt v4, v5, :cond_3

    iget-object v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->mLetters:Ljava/util/ArrayList;

    invoke-virtual {v4}, Ljava/util/ArrayList;->size()I

    move-result v4

    add-int/lit8 v4, v4, -0x1

    iput v4, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->choose:I

    goto :goto_3
.end method

.method public setOnTouchingLetterChangedListener(Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;)V
    .locals 0
    .parameter "onTouchingLetterChangedListener"

    .prologue
    .line 181
    iput-object p1, p0, Lcom/lewa/PIM/widget/AlphabetFastIndexer;->onTouchingLetterChangedListener:Lcom/lewa/PIM/widget/AlphabetFastIndexer$OnTouchingLetterChangedListener;

    .line 182
    return-void
.end method

Тут нас интересует следующий участок

AlphabetFastIndexer.smali

const/16 v0, 0x1c

    new-array v0, v0, [Ljava/lang/String;

    const/4 v1, 0x0

    const-string v2, "u2605"

    aput-object v2, v0, v1

    const/4 v1, 0x1

    const-string v2, "#"

    aput-object v2, v0, v1

    const/4 v1, 0x2

    const-string v2, "A"

    aput-object v2, v0, v1

    const/4 v1, 0x3

    const-string v2, "B"

    aput-object v2, v0, v1

    const/4 v1, 0x4

    const-string v2, "C"

    aput-object v2, v0, v1

    const/4 v1, 0x5

    const-string v2, "D"

    aput-object v2, v0, v1

    const/4 v1, 0x6

    const-string v2, "E"

    aput-object v2, v0, v1

    const/4 v1, 0x7

    const-string v2, "F"

    aput-object v2, v0, v1

    const/16 v1, 0x8

    const-string v2, "G"

    aput-object v2, v0, v1

    const/16 v1, 0x9

    const-string v2, "H"

    aput-object v2, v0, v1

    const/16 v1, 0xa

    const-string v2, "I"

    aput-object v2, v0, v1

    const/16 v1, 0xb

    const-string v2, "J"

    aput-object v2, v0, v1

    const/16 v1, 0xc

    const-string v2, "K"

    aput-object v2, v0, v1

    const/16 v1, 0xd

    const-string v2, "L"

    aput-object v2, v0, v1

    const/16 v1, 0xe

    const-string v2, "M"

    aput-object v2, v0, v1

    const/16 v1, 0xf

    const-string v2, "N"

    aput-object v2, v0, v1

    const/16 v1, 0x10

    const-string v2, "O"

    aput-object v2, v0, v1

    const/16 v1, 0x11

    const-string v2, "P"

    aput-object v2, v0, v1

    const/16 v1, 0x12

    const-string v2, "Q"

    aput-object v2, v0, v1

    const/16 v1, 0x13

    const-string v2, "R"

    aput-object v2, v0, v1

    const/16 v1, 0x14

    const-string v2, "S"

    aput-object v2, v0, v1

    const/16 v1, 0x15

    const-string v2, "T"

    aput-object v2, v0, v1

    const/16 v1, 0x16

    const-string v2, "U"

    aput-object v2, v0, v1

    const/16 v1, 0x17

    const-string v2, "V"

    aput-object v2, v0, v1

    const/16 v1, 0x18

    const-string v2, "W"

    aput-object v2, v0, v1

    const/16 v1, 0x19

    const-string v2, "X"

    aput-object v2, v0, v1

    const/16 v1, 0x1a

    const-string v2, "Y"

    aput-object v2, v0, v1

    const/16 v1, 0x1b

    const-string v2, "Z"

    aput-object v2, v0, v1

Тут и так все понятно, меняем буквы на русские, и так как русских букв больше придется добавить несколько строк типа

    const/16 v1, 0x1b 

    const-string v2, ""

    aput-object v2, v0, v1

const/16 v1, 0x1b это порядковый номер буквы он тоже будет с каждой новой буквой расти. Так же в начале вы могли заметить стоку

const/16 v0, 0x1c

Это размер всего массива, так как мы добавили несколько букв ее нам тоже надо поменять. Я добавил 3 буквы по этому в моем случае ее надо поменять на

const/16 v0, 0x1f

В итоге у меня получился следующий код:

AlphabetFastIndexer.smali Исправленный

const/16 v0, 0x1f

    new-array v0, v0, [Ljava/lang/String;

    const/4 v1, 0x0

    const-string v2, "u2605"

    aput-object v2, v0, v1

    const/4 v1, 0x1

    const-string v2, "#"

    aput-object v2, v0, v1

    const/4 v1, 0x2

    const-string v2, "u0410"

    aput-object v2, v0, v1

    const/4 v1, 0x3

    const-string v2, "u0411"

    aput-object v2, v0, v1

    const/4 v1, 0x4

    const-string v2, "u0412"

    aput-object v2, v0, v1

    const/4 v1, 0x5

    const-string v2, "u0413"

    aput-object v2, v0, v1

    const/4 v1, 0x6

    const-string v2, "u0414"

    aput-object v2, v0, v1

    const/4 v1, 0x7

    const-string v2, "u0415"

    aput-object v2, v0, v1

    const/16 v1, 0x8

    const-string v2, "u0416"

    aput-object v2, v0, v1

    const/16 v1, 0x9

    const-string v2, "u0417"

    aput-object v2, v0, v1

    const/16 v1, 0xa

    const-string v2, "u0418"

    aput-object v2, v0, v1

    const/16 v1, 0xb

    const-string v2, "u041a"

    aput-object v2, v0, v1

    const/16 v1, 0xc

    const-string v2, "u041b"

    aput-object v2, v0, v1

    const/16 v1, 0xd

    const-string v2, "u041c"

    aput-object v2, v0, v1

    const/16 v1, 0xe

    const-string v2, "u041d"

    aput-object v2, v0, v1

    const/16 v1, 0xf

    const-string v2, "u041e"

    aput-object v2, v0, v1

    const/16 v1, 0x10

    const-string v2, "u041f"

    aput-object v2, v0, v1

    const/16 v1, 0x11

    const-string v2, "u0420"

    aput-object v2, v0, v1

    const/16 v1, 0x12

    const-string v2, "u0421"

    aput-object v2, v0, v1

    const/16 v1, 0x13

    const-string v2, "u0422"

    aput-object v2, v0, v1

    const/16 v1, 0x14

    const-string v2, "u0423"

    aput-object v2, v0, v1

    const/16 v1, 0x15

    const-string v2, "u0424"

    aput-object v2, v0, v1

    const/16 v1, 0x16

    const-string v2, "u0425"

    aput-object v2, v0, v1

    const/16 v1, 0x17

    const-string v2, "u0426"

    aput-object v2, v0, v1

    const/16 v1, 0x18

    const-string v2, "u0427"

    aput-object v2, v0, v1

    const/16 v1, 0x19

    const-string v2, "u0428"

    aput-object v2, v0, v1

    const/16 v1, 0x1a

    const-string v2, "u0429"

    aput-object v2, v0, v1

    const/16 v1, 0x1b

    const-string v2, "u042b"

    aput-object v2, v0, v1

    const/16 v1, 0x1c

    const-string v2, "u042d"

    aput-object v2, v0, v1

    const/16 v1, 0x1d

    const-string v2, "u042e"

    aput-object v2, v0, v1

    const/16 v1, 0x1e

    const-string v2, "u042f"

    aput-object v2, v0, v1

«u042f» — это «юникоды» наших букв, так надежней)

После этого можно попробовать собрать риложение перетянув папку PIM на apktool-b.cmd, через некоторое время появится PIMdistPIM.apk

Теперь можно заменить им PIM.apk своего телефона, как это сделать выходит за рамки данной статьи. Могу лишь скзать что можно прошится моим патчем, предварительно заменив в нем PIM.apk на свой.

PROFIT?

Не совсем… Да, буквы русские но поиск то не работает!
Изучаем дальше декомпилированный AlphabetFastIndexer.smali
тут больше ничего интересного кроме

public static abstract interface OnTouchingLetterChangedListener
  {
    public abstract void onTouchingLetterChanged(String paramString);
  }

Хотя по идее он к нашей проблеме не относится я все же решил посмотреть что это такое. public static abstract говорит о том, что этот интерфейс реализован где то в другом файле. Ищем поиском и находим пару файлов где встречается OnTouchingLetterChangedListener:
PIMsmalicomlewaPIMcontactslistContactEntryListFragment.smali
PIMsmalicomlewaPIMmmschoiceContactsMmsChoicePhoneNumbersContacts.smali

Они достаточно длинные поэтому приведу только то что нас интересует

ContactEntryListFragment.smali

Runnable FirstLettersRunnable = new Runnable()
  {
    public void run()
    {
      ContactEntryListFragment.this.marrFirstCharacters.clear();
      ContactEntryListFragment.this.marrFirstLetters.clear();
      Cursor localCursor = ContactEntryListFragment.this.mAdapter.getCursor(0);
      CharArrayBuffer localCharArrayBuffer1;
      CharArrayBuffer localCharArrayBuffer2;
      if ((localCursor != null) && (!localCursor.isClosed()) && (localCursor.getCount() > 0))
      {
        localCursor.moveToFirst();
        boolean bool = ContactEntryListFragment.this.mAdapter instanceof ContactEntryListAdapter;
        int i = 0;
        int j = 0;
        if (bool)
          j = ContactEntryListFragment.this.mAdapter.getStarredCount();
        do
        {
          localCharArrayBuffer1 = new CharArrayBuffer(128);
          localCharArrayBuffer2 = new CharArrayBuffer(128);
          if ((i >= j) || (localCursor.getInt(12) != 1))
            break;
          localCharArrayBuffer1.data[0] = '★';
          int k = 9733;
          i++;
          ContactEntryListFragment.this.marrFirstLetters.add(String.valueOf(k));
          ContactEntryListFragment.this.marrFirstCharacters.add(String.copyValueOf(localCharArrayBuffer1.data, 0, 1));
        }
        while (localCursor.moveToNext());
        if (ContactEntryListFragment.this.mAdapter != null)
          ContactEntryListFragment.this.mAdapter.notifyDataSetChanged();
      }
      ContactEntryListFragment.access$302(ContactEntryListFragment.this, true);
      return;
      localCursor.copyStringToBuffer(1, localCharArrayBuffer1);
      if ((localCharArrayBuffer1.data[0] >= 'a') && (localCharArrayBuffer1.data[0] <= 'z'))
      {
        char[] arrayOfChar = localCharArrayBuffer1.data;
        arrayOfChar[0] = ((char)('¢' + arrayOfChar[0]));
      }
      while (true)
      {
        localCursor.copyStringToBuffer(10, localCharArrayBuffer2);
        int m = Character.toUpperCase(localCharArrayBuffer2.data[0]);
        if ((m >= 65) && (m <= 90))
          break;
        m = 35;
        break;
        if ((localCharArrayBuffer1.data[0] < '€') && ((localCharArrayBuffer1.data[0] < 'A') || (localCharArrayBuffer1.data[0] > 'Z')))
          localCharArrayBuffer1.data[0] = '#';
      }
    }
  };

Как и откуда вызывается это функция я не понял но факт — она собирает первые буквы контактов и все что не относится к английским буквам приравневает к # И поэтому у нас ничего не работает… конкретно эта функция находится в «подфайле» PIMsmalicomlewaPIMcontactslistContactEntryListFragment$3.smali

Там нужно найти участок

.method public run()V
    .locals 13

    .prologue
    .local p0, this:Lcom/lewa/PIM/contacts/list/ContactEntryListFragment$3;,"Lcom/lewa/PIM/contacts/list/ContactEntryListFragment.3;"
    const/16 v12, 0x5a

    const/16 v11, 0x41

0x41 и 0x5a это буквы ‘A’ и ‘Z’ их надо поменять на русские:

.method public run()V
    .locals 13

    .prologue
    .local p0, this:Lcom/lewa/PIM/contacts/list/ContactEntryListFragment$3;,"Lcom/lewa/PIM/contacts/list/ContactEntryListFragment.3;"
    const/16 v12, 0x42f

    const/16 v11, 0x410

После чего найти


    aget-char v6, v6, v8

    const/16 v7, 0x61

    if-lt v6, v7, :cond_6

    iget-object v6, v3, Landroid/database/CharArrayBuffer;->data:[C

    aget-char v6, v6, v8

    const/16 v7, 0x7a

    if-gt v6, v7, :cond_6

0x61 — ‘a’
0x7a — ‘z’
Меняем


       aget-char v6, v6, v8

    const/16 v7, 0x430

    if-lt v6, v7, :cond_6

    iget-object v6, v3, Landroid/database/CharArrayBuffer;->data:[C

    aget-char v6, v6, v8

    const/16 v7, 0x44f

    if-gt v6, v7, :cond_6

В файле MmsChoicePhoneNumbersContacts.smali примерно такая же история

ContactEntryListFragment.smali

    protected void onQueryComplete(int paramInt, Object paramObject, Cursor paramCursor)
    {
      switch (paramInt)
      {
      default:
        return;
      case 0:
      }
      MmsChoicePhoneNumbersContacts.this.mAdapter.changeCursor(paramCursor);
      if (paramCursor.getCount() > 0)
      {
        MmsChoicePhoneNumbersContacts.this.marrFirstCharacters.clear();
        MmsChoicePhoneNumbersContacts.this.marrFirstLetters.clear();
        paramCursor.moveToPosition(-1);
        if (paramCursor.moveToNext())
        {
          CharArrayBuffer localCharArrayBuffer1 = new CharArrayBuffer(128);
          paramCursor.copyStringToBuffer(4, localCharArrayBuffer1);
          if ((localCharArrayBuffer1.data[0] >= 'a') && (localCharArrayBuffer1.data[0] <= 'z'))
          {
            char[] arrayOfChar = localCharArrayBuffer1.data;
            arrayOfChar[0] = ((char)('¢' + arrayOfChar[0]));
          }
          while (true)
          {
            CharArrayBuffer localCharArrayBuffer2 = new CharArrayBuffer(128);
            paramCursor.copyStringToBuffer(11, localCharArrayBuffer2);
            char c = Character.toUpperCase(localCharArrayBuffer2.data[0]);
            if ((c < 'A') || (c > 'Z'))
              c = '#';
            MmsChoicePhoneNumbersContacts.this.marrFirstLetters.add(String.valueOf(c));
            MmsChoicePhoneNumbersContacts.this.marrFirstCharacters.add(String.copyValueOf(localCharArrayBuffer1.data, 0, 1));
            break;
            if ((localCharArrayBuffer1.data[0] < '€') && ((localCharArrayBuffer1.data[0] < 'A') || (localCharArrayBuffer1.data[0] > 'Z')))
              localCharArrayBuffer1.data[0] = '#';
          }
        }
        MmsChoicePhoneNumbersContacts.access$502(MmsChoicePhoneNumbersContacts.this, true);
        paramCursor.moveToFirst();
        MmsChoicePhoneNumbersContacts.this.mEmptyTextView.setVisibility(8);
        return;
      }
      MmsChoicePhoneNumbersContacts.this.mEmptyTextView.setVisibility(0);
    }

# virtual methods
.method protected onQueryComplete(ILjava/lang/Object;Landroid/database/Cursor;)V
    .locals 10
    .parameter "token"
    .parameter "cookie"
    .parameter "cursor"

    .prologue
    const/16 v9, 0x5a

    const/16 v8, 0x41

Меняем на

# virtual methods
.method protected onQueryComplete(ILjava/lang/Object;Landroid/database/Cursor;)V
    .locals 10
    .parameter "token"
    .parameter "cookie"
    .parameter "cursor"

    .prologue
    const/16 v9, 0x42f

    const/16 v8, 0x410

и соответсвенно

    aget-char v3, v3, v5

    const/16 v4, 0x61

    if-lt v3, v4, :cond_3

    iget-object v3, v1, Landroid/database/CharArrayBuffer;->data:[C

    aget-char v3, v3, v5

    const/16 v4, 0x7a

    if-gt v3, v4, :cond_3

на

    aget-char v3, v3, v5

    const/16 v4, 0x430

    if-lt v3, v4, :cond_3

    iget-object v3, v1, Landroid/database/CharArrayBuffer;->data:[C

    aget-char v3, v3, v5

    const/16 v4, 0x44f

    if-gt v3, v4, :cond_3

Собираем это дело обратно и запихиваем а телефон. Вот теперь работает!

Спасибо всем за внимание!

P.S. Надеюсь мой ход мыслей кому то поможет. В идеале бы найти как строятся группы в списке контактов и привинтить это дело сюда. Тогда бы в этом списке были толко те буквы, которые дейсвительно присутствуют в контактах, при том что на нескольких языках одновременно, но это мне пока не по зубам.


apk


В процессе использования разнообразных прошивок для Android телефонов и планшетов порой возникает желание тем или иным образом изменить встроенные в операционную систему приложения. В данной статье мы подробно опишем этот процесс. Само собой, что разобрать и собрать обратно системный APK-файл нужно так, чтобы он работал стабильно. Разберем по пунктам, что и как для этого нужно сделать.

1 Для начала Вы должны Дедоксировать Ваши файлы

2 После того как вы декомпилировали приложение выбираем то приложение которое вы собираетесь редактировать и разбираем, пускай оно будет называться framework-res.apk и у себя в уме пометьте его как Оригинальное приложение 1.

3 После того как вы отредактировали приложение вам необходимо его упаковать, то что собралось назовем его в уме Модифицированное приложение 2.

4 Теперь объясняю, зачем нужно было в уме запоминать приложения как оригинальное и модифицированное 2. Собранное программой ApkTool приложение работать не будет, но это не проблема. Выполняем следующие действия:

Как редактировать системные apkКак редактировать системные apkКак редактировать системные apkКак редактировать системные apk

Сжимать в режиме «Обычный»

5 После того как вы заменили содержимое. Можете забрасывать это приложение в вашу прошивку либо систему.

Статьи по теме APK:

  • Что такое APK?
  • Необходимые инструменты для работы с APK
  • Как устанавливать приложения для Android с расширением apk
  • Как удалить приложения (программы, игры) на android?
  • Как скачивать и покупать приложения с Google Play
  • Что такое root в Android?
  • Структура APK файла
  • Разборка (декомпиляция) APK файла с помощью Apktool
  • Локализация файла APK
  • Упаковка APK приложения и подпись (компиляция и подпись)
  • Выбор места установки приложения APK
  • Редактирование и замена иконок в APK
  • Узнаем какие права у приложения APK
  • Как извлечь установочный файл с приложением (.apk) из системы
  • Как удалить рекламу из приложений APK
  • Как скачать приложение APK на компьютер с Google Play
  • Какие встроенные (системные) приложения Android можно удалить
  • Деодексирование системных приложений в Андроид
  • Как редактировать системные apk
  • Как получить исходный код приложения с расширением Apk
  • Одексирование Android приложений


Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить системное имя флешки
  • Как изменить системное время через командную строку
  • Как изменить системное время на сервере
  • Как изменить системное время на компьютере windows 10
  • Как изменить сири на другой голос

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии