Добрый день!
Хочу поделиться с вами историей как я модифицировал одно из системных приложений 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 и начал изучать.
<?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>
Там меня заинтересовала строчка />. Что это за индексер такой?? Смотрим
<?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
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
.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
Тут нас интересует следующий участок
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 v0, 0x1c
Это размер массива, и т.к. русских букв больше на придется добавит несколько строк типа
const/16 v1, 0x1b
const-string v2, ""
aput-object v2, v0, v1
и помеять эту константу. const/16 v1, 0x1b это порядковый номер буквы он тоже будет с каждой буквой расти.
У меня получилось так:
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
Они достаточно длинные поэтому приведу только то что нас интересует
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 примерно такая же история
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. Надеюсь мой ход мыслей кому то поможет. В идеале бы наити как строятся группы в списке контактов и привинтить это дело сюда. Тогда бы в этом списке были толко те буквы, которые дейсвительно присутствуют в контактах, при том что на нескольких языках одновременно, но это мне пока не по зубам.
Автор: NioriX