そもそも需要がないと思いますが。(笑)
技術的な詳細などは全て、日本のMotorola端末mod界の巨匠、meyskld大先生がまとめて下さっております。
あれ: Motorola Milestone2のBatteryLevelを1%Stepにしてみた
http://ar3r3.blogspot.com/2011/02/motorola-milestone2batterylevel1step.html
悩んだのはapktoolの使い方で、apkに対する手順は探すとけっこう見つかるのですが、jarに対するそれがなかなか見つかりませんでした。ただ色々調べてみたところ、違うのはファイルの差し替え部分くらいで、apkはzip扱いにして7z無圧縮、jarはjarコマンドで無圧縮更新、とすればOKらしい事が判明。
というわけで、ざっくりとした手順おば。
まずはターゲットとなる/system/framework/services.jarをadb pull等で拾ってきましょう。
そしたらapktoolを使って内容をバラします。
apktool d services.jar
修正の対象となるファイルは、services.jar.out/smali/com/android/server/BatteryService.smaliです。
適当なエディタで開いて、以下の3ヶ所を変更します。
まずはけっこう最初の方。.fieldを1行追加。
# instance fields
.field private mAcOnline:Z
.field private mBatteryHealth:I
.field private mBatteryLevel:I
.field private mBatteryLevel1Step:I
.field private mAcOnline:Z
.field private mBatteryHealth:I
.field private mBatteryLevel:I
.field private mBatteryLevel1Step:I
次に真ん中へんよりちょっと上くらい。オリジナルを1行コメントアウトして、下に2行追加。
.line 352
const-string v2, "level"
#iget v3, p0, Lcom/android/server/BatteryService;->mBatteryLevel:I
invoke-direct {p0}, Lcom/android/server/BatteryService;->getBatteryLevel1Step()V
iget v3, p0, Lcom/android/server/BatteryService;->mBatteryLevel1Step:I
invoke-virtual {v1, v2, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;
最後はずっと下の方。関数1つまるまる追加。
.method final getBatteryLevel()I
.locals 1
.prologue
.line 175
iget v0, p0, Lcom/android/server/BatteryService;->mBatteryLevel:I
return v0
.end method
.method private getBatteryLevel1Step()V
.locals 8
.prologue
.line 30
const/4 v4, 0x0
.line 32
.local v4, reader:Ljava/io/FileReader;
:try_start_0
new-instance v5, Ljava/io/FileReader;
const-string v6, "/sys/class/power_supply/battery/charge_counter"
invoke-direct {v5, v6}, Ljava/io/FileReader;->(Ljava/lang/String;)V
:try_end_0
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_1
.end local v4 #reader:Ljava/io/FileReader;
.local v5, reader:Ljava/io/FileReader;
move-object v4, v5
.line 35
.end local v5 #reader:Ljava/io/FileReader;
.restart local v4 #reader:Ljava/io/FileReader;
:goto_0
const/16 v6, 0x14
:try_start_1
new-array v1, v6, [C
.line 36
.local v1, buf:[C
invoke-virtual {v4, v1}, Ljava/io/FileReader;->read([C)I
move-result v3
.line 37
.local v3, read:I
invoke-virtual {v4}, Ljava/io/FileReader;->close()V
.line 38
new-instance v0, Ljava/lang/String;
const/4 v6, 0x0
invoke-direct {v0, v1, v6, v3}, Ljava/lang/String;->([CII)V
.line 39
.local v0, batteryLevelsysfs:Ljava/lang/String;
const-string v6, "\n"
const-string v7, ""
invoke-virtual {v0, v6, v7}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
move-result-object v0
.line 40
invoke-static {v0}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v2
.line 41
.local v2, mBatteryLevel1Step:I
const/16 v6, 0x64
if-lt v2, v6, :cond_0
.line 42
const/16 v2, 0x64
.line 45
:cond_0
sget-object v6, Ljava/lang/System;->out:Ljava/io/PrintStream;
#invoke-virtual {v6, v2}, Ljava/io/PrintStream;->println(I)V
iput v2, p0, Lcom/android/server/BatteryService;->mBatteryLevel1Step:I
:try_end_1
.catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0
.line 52
.end local v0 #batteryLevelsysfs:Ljava/lang/String;
.end local v1 #buf:[C
.end local v2 #mBatteryLevel1Step:I
.end local v3 #read:I
:goto_1
return-void
.line 48
:catch_0
move-exception v6
goto :goto_1
.line 33
:catch_1
move-exception v6
goto :goto_0
.end method
これで修正作業完了。ビルドします。
apktool b service.jar.out
完成したclasses.dexを元のservices.jarに追加(差し替え)します。
cd services.jar.out/build/apk
jar u0vf classes.dex ../../../services.jar
jar u0vf classes.dex ../../../services.jar
あとはadb push等で元のservices.jarと差し替えて、再起動したら完了です。
1%刻みに慣れてしまうと、もう10%刻みには戻れません。
値はちゃんと拾えてるんだから、どうしてデフォルトで1%刻みにしてくれないかな…。
めいじゅーさん、ありがとごじましたー!!