2012年12月29日土曜日

【Xperia AX SO-01E】framework-res.apk をいじらずにカスタムする方法(1)

Xperiaのシステムをカスタマイズしようとしたとき、「framework-res.apk」をいじりたくなることがあります。
ところがところが、2012年以降のXperiaでは、framework-res.apkをデコード、(いじるいじらないにかかわらず)ビルドし直したものを端末に戻しても、上手く動きません(ブートループになってしまう)。
いろいろ小細工をして、動くframework-res.apkを生成する方法を編み出した賢者さんもいらっしゃいますが、テーマの背景が適用されなくなるといった副作用があるようです(私は未検証)。

そこで、framework-res.apkそのものはいじらずに、別のapkをこしらえてオーバーレイし、リソースをすげ替える方法を検証してみました。おそらくGXやSXでも通用するのではないかと思われます(持ってないのでもちろん未検証)。
※SO-03Dの方がいろいろ検証しておられます。これについては記事の最後に追記しました。機種によってはマニフェストの記述やapkのファイル名・置き場所が異なったり厳密になっていたりするようですね。
今回は例として、「電源を切る」の部分のアイコンと文字を変えてみます。
(注:下記画像では、メニューに「再起動」がありますが、今回のカスタムとは無関係です。)

なお今回の方法では、framework-res.apkにリソースの追加は出来ないようです(元々無いリソースをオーバーレイapkに追加したとしても、他から参照出来ない)が、それに関しては次回の記事で検証します。


前提(私の実験環境)は以下です。
・rootとってあること
・作業PCはadbコマンドが使える環境であること
・作業PCにjavaが入っていること
・端末のビルド番号は9.0.G.0.247
・CWMを導入してあること
・母艦はWindows 7
・トラブっても自力で復旧できること(つまり自己責任)

■必要物資
・aapt.exe(Android SDKにも含まれていますが、最新版がベター)

aapt.exeは、「apktool」で検索した先でゲット。
apktoolのダウンロードページに「apktool-install-windows-うんたらかんたら.tar.bz2」というのがありますが、その中に含まれています。

■1.PCにおける作業フォルダの準備
ここでは「c:\apkwork」とします。
この中に、「new」「framework-res-custom」フォルダを(無ければ)新規作成します。
必要物資たちは作業フォルダ直下にぶっこみます。

□apkwork ┳ □new(生成されたframework-res-custom.apkが入る予定)
     ┣ □framework-res-custom(ソースファイル群が入る)
     ┗ aapt.exe

■2.ソースファイル作成
「framework-res-custom.apk」というファイルを作成するため、各種ファイルを捏造します。

【2-1】「AndroidManifest.xml」作成
テキストエディタで以下の内容を打ち込み、framework-res-customフォルダ内に「AndroidManifest.xml」という名前で保存します。

<?xml version="1.0" encoding="utf-8"?>
<manifest package="android.overlay.custom"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <overlay target="android" priority="100" />
</manifest>

【2-2】リソース作成
 framework-res-customフォルダ内に「res」フォルダを新規作成し、さらにその中に「drawable-xhdpi」「values」「values-ja」フォルダを新規作成します。

すげ替えたいアイコンのpng画像ファイル(64×64)を準備し、「ic_lock_power_off.png」という名前にしてdrawable-xhdpiフォルダに投入。

テキストエディタで以下の内容を打ち込み、valuesフォルダ内に「strings.xml」という名前で保存します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="global_action_power_off">Shutdown</string>
</resources>

さらにテキストエディタで以下の内容を打ち込み、values-jaフォルダ内に「strings.xml」という名前で保存します。これは日本語が含まれていますので、必ず文字コード「UTF-8N」で保存のこと。さもなくば華麗に文字化けします。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="global_action_power_off">電源断</string>
</resources>

2つのフォルダに同じような「strings.xml」を作りましたが、「values-ja」の方は端末の設定が日本語の時に、「values」の方は日本語以外の時に表示される文字列になります。

ちなみにpublic.xmlは不要。リソースIDはapk生成時に勝手に振られます。
また振られるリソースIDは「0x7fxxxxxx」となり、オリジナルのIDとは別物になりますが、特に影響は無いようなので気にしなくて大丈夫です。

結果的に、framework-res-customフォルダ内の構成は以下のようになります。

□framework-res-custom ┳ □res ┳ □drawable-xhdpi ━ ic_lock_power_off.png
            ┃    ┣ □values ━ strings.xml
            ┃    ┗ □values-ja ━ strings.xml
            ┗ AndroidManifest.xml

■3.apk生成
「apkwork」フォルダでコマンドプロンプトを開き、以下のコマンドを実行します。

C:\apkwork>aapt package -S framework-res-custom\res -M framework-res-custom\AndroidManifest.xml -f -v -F new\framework-res-custom.apk

newフォルダにframework-res-custom.apkが生成されます。

■4.端末をCWMモードにして待機
以降は端末をCWMモードにして作業をすすめます。
CWMが起動したら、「mounts and storage」に入り、「mount /system」と「mount /data」をしておきます。
もちろんPCと端末はUSBでつないでおいてください。

■5.ファイルを端末にぶっこむ
C:\apkwork>adb push new\framework-res-custom.apk /data/local/tmp

多分、rootをとった時に/data/local/tmpは作られていると思うので、それ前提です。

■6.framework-res-custom.apkのパーミッション変更
以降は端末のシェルに入っての作業となります。

C:\apkwork>adb shell
~ # cd /data/local/tmp
/data/local/tmp # chmod 0644 framework-res-custom.apk

■7.framework-res-custom.apkを所定の位置にコピー、一旦再起動
/data/local/tmp # cp framework-res-custom.apk /system/vendor/overlay
/data/local/tmp # reboot

/system/vendor/overlayにapkを配置。ここに置いたapkは元のapkに優先して活躍してくれます。
rebootで一旦再起動。

■8.ロック画面後、もっかい再起動
まずロック画面が出てくるまで待機してください。
最初の再起動では、オーバーレイは反映されず、アイコンと文字はまだ変化無しだと思います。
ただこの時、端末内部では自動的にいろいろなものが生成されています。(/data/resource-cache内に「vendor@overlay@@framework-res-custom@idmap」、/data/system/overlay/system@framework@framework-res.apk内(ディレクトリかよ)に「0100」(シンボリックリンク)が出来ています。)
もう一回再起動し、変更が反映されていればめでたしめでたし。

なお、このカスタムを元に戻すには、framework-res-custom.apkを削除するほか、上記2つのキャッシュ(?)も削除した方が良いでしょう。

■他機種の場合
Xperia acro HD(SO-03D)の方が検証された結果、以下の条件が必要であるようです。
・「AndroidManifest.xml」内の<manifest>タグ、packageの値は「android」でないといけない
・オーバーレイapkのファイル名は「framework-res.apk」つまりオリジナルと同一でないといけない
・オーバーレイapkの置き場所は「/system/vendor/overlay/framework」

他機種でframework-res.apkのオーバーレイをされる方は参考にしてください。

8 件のコメント:

  1. acroHD(SO-03D)で試してみましたが、/data/resource-cache内のファイルはありましたが、もう一つの方が作成されてませんでした。
    この機種では無理なようですね。

    返信削除
    返信
    1. SO-01Eでも試行錯誤の果てにこの手順にいたりましたが、機種によってはapkの置き場所とか微妙に違うのかもしれません。
      情報が少なすぎる…。

      削除
    2. apkファイルを/system/vendor/overlay/frameworkに置いたら両方のファイルが出来ました。
      しかし、通常のアプリ(ホームアプリなど)が異常終了してしまう…なかなかうまく行きませんね。。。

      削除
    3. 最初そこに置こうとしてたんですが、SO-01Eだと逆に、そこにapk置いたら無視されました。

      同じ場所に他のapkがすでにある場合、AndroidManifest.xmlのoverlayタグのpriorityの値をずらさないとやばいかもしれません。
      SO-01Eは「android-res.apk」というのが元々あり、それがpriority="200"となっていたので、framework-res-custom.apkはpriority="100"としてみました。

      削除
    4. SO-03Dの場合は/system/vendor/overlay/frameworkにはテーマapkファイルがあるんです。
      ただ、そのapkファイルをデコンパイルしてAndroidManifest.xmlを覗いてみたんですがoverlayタグ自体が無いんです。
      でも/data/resource-cacheにはそのapkの奴があるんですよね。
      もうわけがわからなくなってますw

      削除
    5. 一応試してみたことをwikiの研究室に列記しました。
      もしヒントがあればお願いします。

      削除
    6. 試行錯誤の結果、なんとかオーバーレイに成功しました。

      削除
    7. おめでとうございます。
      当記事にその件追記しました。
      私も今後の参考にさせていただきます、ありがとうございました。

      削除