[RAZR i]ナビゲーションバーをカスタマイズ

Android OS

すっかりメイン端末としての不動の地位を確立したRAZR iのカスタマイズをするのが楽しいw

ディスプレイ大型化の風潮の中でRAZR iは小ぶりに類する端末ですが、それにしたって片手操作は難しいと思う。
やはりメニューボタンが画面上にあるのはおかしいGUIだと思います。
主要なメニューを画面下部に移動させれば、片手操作もしやすくなるのではと思い立ち、ナビゲーションバーのカスタマイズに乗り出しました。

ほとんど自分用のメモです。

必要なもの

  • Android SDK
    adbとか使うのに必要。
  • Java6
    Java7でも多分大丈夫。
  • rooted
  • deodexedなSystemUI.apk
  • APK Multi Tool
    広告がちょっとうざい。けど、サイトがDrupalで出来ているのがぐっど。
  • 自己責任

環境

  • Windows7 on Virtual Box
  • UTF-8が扱えるエディタ。
    今回はサクラエディタを使用させてもらいました。

参考にしたサイト

必要なファイルを引っこ抜く

最低限必要なのは

  • /system/app/SystemUI.apk
  • /system/framework/framework-res.apk

の2つ。
ということでこれをRAZR iから引っこ抜く。
adb接続して

adb pull /system/app/SystemUI.apk
adb pull /system/app/framework-res.apk

これをバックアップ用、改造用と一応分けておく。

とやっておきたいのですが、「SystemUI.apk」はディレクトリを見て分かるように、「SystemUI.apk」と「SystemUI.odex」の2つに分かれてしまっています。
今回、SystemUI.apkをいじるにはSystemUI.apkをdeodex化しておかないと、実行ファイル部分がいじれない状態になってしまいます。(という理解でいいのかな?)
生玉子の黄身(odex-Optimized Dalvik EXcutable)だけが外に出ちゃってるので、殻の中(apk)に戻しちゃいましょう、みたいな。なんか違うかw

そこでSystemUI.apkをdeodex化するには

を使うメジャーなやり方があります。
ただし、これさえも面倒だと思ったのですでにdeodex化されたファイルがありますのでそちらを流用したいと思います。

ZIPファイルを解凍して、SystemUI.apkを引っこ抜いておく。
ディレクトリを見て分かるように、odexファイルがない。

これをつかうにあたり、自分のシステム情報をきちんと確認する。
ついでに/system/framework/framework-res.apkも取り出しておく。

APK multi toolのセットアップ。

これはもうXperia Freaksさんのところでよくまとめられていますね。スバラシイ。

自分のインストールした場所はC:\直下。

必ず最初に先ほど引っこ抜いた「SystemUI.apk」「framework-res.apk」を「APK multi tool\other」フォルダ内に置く。

あとは「Setup.bat」を実行。
最初だからといって、1から実行しない。してもいいけど。
最初は「3」

3. Setup Directories
 This will setup the appropate directories needed by Apk Multi-Tools
 (This script only needs to be ran for first time users do not use if your
 Just updating from previous Version)

これで新たなフォルダが出来上がる。

その後、「2」を実行。

* 2. Installing Framework-Res
* This Will install one of the Framwork-Res Files for 1.x/2.x/3.x/4.x
* This Feature also will install any of the other Dependencies needed
* In order to use this feature make sure to drop all of the needed files
* into the other Folder or else this script will not find them *

メッセージが変わって、「1」を実行。DOS窓が消えるので再度、Setup.batから入っていって、「4」を実行。

***********************************
*
* 1. Install framework-res.apk
*
***********************************
*
* 4. Install SystemUI.apk
*
***********************************

インストールが無事に終わればなんとかかんとか「Complete」と出る。一瞬だからメッセージがよく分からないw

作業開始。

ファイルを置く。

「C:\APK-Multi-Tool\place-apk-here-for-modding」フォルダに「SystemUI.apk」を入れる。

んで、ようやくここから作業が出来る。

「Script.bat」を実行。
多分こんな感じ。
バージョンによって若干、メニューが変わっているところもある。

この中から、最初に「プロジェクト」を作成する。

24 Set current project

を実行するので「24」と打ち込む。多分、

- 1 - SystemUI.apk

とあるので「1」を実行。
画面上部にステータスが表示されているので確認。

------------------------------------------------------------------------------------------------------------------
| Compression-Level: 9 | Heap Size: 512mb | Decompile : Sources and Resources Files | Current-App: SystemUI.apk |
------------------------------------------------------------------------------------------------------------------

一番上の右端。

デコンパイル

画面真ん中上部に注目。

------------------------------------
Advanced Tasks Such As Code Editing
------------------------------------
9 Decompile apk

とあるので「9」を実行。

成功すると「project\SystemUI.apk」フォルダ内にファイルが出来ているはず。

もし、deodex化されていないapkをデコンパイルすると「smali」ディレクトリがない。

ファイルの編集

ここからはサクラエディタで作業。

ここからの作業は解説が先人のおかげで充実しています。
けど自分のメモなのであえて、流れを追っていきます。

前述したとおり

のまんまです。

まず、このやり方を適用できるのは「Ice Cream Sandwitch」と「Jelly Bean」なandroid4.0.x以降のOSです。

追加しなければならないファイルは

  • \res\drawable-xhdpi\ic_sysbar_menu.png
  • \res\drawable-xhdpi\ic_sysbar_menu_land.png
  • \res\drawable-xhdpi\ic_sysbar_search.png (new)
  • \res\drawable-xhdpi\ic_sysbar_search_land.png (new)

で、これらはネット上から集めることができます。
まあだいたいXDAに落ちていますが。

からお好きなpngファイルを落としておきましょう。
落としたはいいけど、入れるべきディレクトリが複数あって困ります。
「hdpi」だの「mdpi」だのよくわかりません。
そこで必要になってくるのは「dpi」。

計算式とかあっていろいろと面倒ですがアプリを入れてしまいます。

Google Playでインストールして起動。
「This Device Info」->「displayinfo」から調べられます。
「densityDpi」の数字を見ておく。RAZR iは「240」

ここのサイトを参考に。

drawable 160dpi
drawable-ldpi 120dpi
drawable-mdpi 160dpi
drawable-hdpi 240dpi
drawable-xhdpi 320dpi
drawable-nodpi Density非依存

とあるのでRAZR iは「hdpi」なんだなと。詳しい理屈は抜き。

先ほど落としたpngファイルを「APK-Multi-Tool\projects\SystemUI.apk\res\drawable-hdpi」フォルダにぶち込みます。上書きもおっけー。

ただし、後ほどこれらのファイルを指定するところがあるので何を追加したか分かるようにしておくこと。
自分がぶっこんだのはこれら。

入れたはいいけど「ic_sysbar_menu_land_big.png」とかは使わねぇw。

次にファイルを編集します。
サクラエディタでいじるファイルは

  • \res\values\public.xml
  • \res\layout\navigation_bar.xml
  • \res\values\ids.xml
  • \res\values\strings.xml
  • \smali\com\android\systemui\statusbar\phone\NavigationBarView.smali

です。

まずは「public.xml」から。

そもそも「検索」なんていうリソースはこのapkに入っておらずそれを登録してあげないといけない、と。
それを登録するファイルが「\res\values\public.xml」です。

サクラエディタで開いてみると

見て分かるように右下に「SJIS」とモロ書いてあるので、これを何とかする。
ファイル->開き直す->UTF-8で開き直すを選べばオッケー。

見た目は変わらないけど、右下に「UTF-8」となっているのを確認する。
改行コードはそのままでオッケーでした。

開いたら末尾の1行前に追記。

	<public type="id" name="recent_remove_item" id="0x7f0f00c0" />
	<public type="id" name="recent_inspect_item" id="0x7f0f00c1" />
	<public type="id" name="search" id="0x7f0f00c2" />
</resources>

searchというIDを追記して、IDに対して独自番号を割り振る、みたいな感じ。 seachの前の「0x7f0f00c1」の16進数の数字を加増させればオッケー。 ということで「searchには「0x7f0f00c2」を割り当てる。あ 「0x7f0f00c2」は唯一なものにしなければならないので、多分大丈夫だと思うけれど、念の為検索して同じ値がないか確認しておく。
これで保存して終わり。 はい、次へ。
それとあとで「0x7f0f00c2」を使う場所が出てくるので、メモしておくなりしておく。

コレは何を意味してるか分からん

分からないけど、やらなければならない。 「 \res\values\ids.xml を開く。UTF-8で開くことを忘れずに。末尾から一行手前、</resorurces>の上に

<item type="id" name="search">false</item>

を追記する。
こんな感じ。

	<item type="id" name="recent_remove_item">false</item>
	<item type="id" name="recent_inspect_item">false</item>
 <item type="id" name="search">false</item>
</resources>

続いて「\res\values\strings.xml」を開く。
同じく末尾から一行手前、</resorurces>の上に

<string name="accessibility_search">search</string>

を追記する。

	<string name="status_bar_toggle_disable_airplane">Toggle disabled in Airplane mode</string>
	<string name="status_bar_toggle_disable_data">Toggle disabled while mobile data off</string>
	<string name="accessibility_search">search</string>
</resources>

まぁこんな感じ。

次に「検索」ボタンの機能を定義します。

  • \smali\com\android\systemui\statusbar\phone\NavigationBarView.smali

をUTF-8で開くと。

「.method public getRecentsButton()Landroid/view/View;」の定義の後ろに下のコードを追記します。
エディタの検索機能でジャンプしてみてください。

.method public getSearchButton()Landroid/view/View;
	.locals 2

	.prologue
	.line 73
	iget-object v0, p0, Lcom/android/systemui/statusbar/phone/NavigationBarView;->mCurrentView:Landroid/view/View;

	const v1, 0x7f0f00c2

	invoke-virtual {v0, v1}, Landroid/view/View;->findViewById(I)Landroid/view/View;

	move-result-object v0

	return-object v0
.end method

ちなみにいま作業しているRAZR iのものだと852行目が「.method public getRecentsButton()Landroid/view/View;」にあたり、866行目の「.end method」でgetRecentsButtonの定義が終わります。
そこから一行開けて上記の検索コードを定義をはっつけます。
同じくRAZR iのものだと868行目あたりかな。

このとき注意しなければならないのは上の画像で言うところの875行目、
「const v1, ・・・・・・」の「・・・・・・」部分には先程のpublic.xmlで定義した検索キーのIDを貼り付けないといけない、と。

	iget-object v0, p0, Lcom/android/systemui/statusbar/phone/NavigationBarView;->mCurrentView:Landroid/view/View;

	const v1, 0x7f0f00c2

これで検索ボタンのコードが追記できました。と書いてありましたのでそういうことなんでしょう。

ロックスクリーンとかの画面で追加したボタンを表示させないための設定。

そのまま続けます。
また検索機能を使って「.method public setDisabledFlags(IZ)V」を探し出します。
自分の環境だと1103行目あたり。

.method public setDisabledFlags(IZ)V
    .locals 7
    .parameter "disabledFlags"
    .parameter "force"

と書いてある「.locals 7」の「7」に2を足して「9」とします。

.method public setDisabledFlags(IZ)V
    .locals 9
    .parameter "disabledFlags"
    .parameter "force"

とする、と。

今度は上記の追記したところから70行目あたり下に移動します。今回の場合だと1174行目。
「invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/NavigationBarView;->getHomeButton」で検索してみるとすぐに出てくるかな。
似たようなものが検索に上がってきてしまうことが多々あるので注意。

こんなところ。

    invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/NavigationBarView;->getHomeButton()Landroid/view/View;

    move-result-object v6

    if-eqz v1, :cond_5

    move v4, v5

んで 「->getHomeButton」の下、「move-result-object v6」の下に一行開けて下記のコードを追記します。

	invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/NavigationBarView;->getMenuButton()Landroid/view/View;

	move-result-object v7

	invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/NavigationBarView;->getSearchButton()Landroid/view/View;

	move-result-object v8

上では「move-result-object v7」「move-result-object v8」とがあるけど、もともとの「move-result-object v6」に数字を加算していきます。元々が仮に「move-result-object v7」なら追記するコードのところはv8、v9となる、と。

こんな感じ。

 

今足したコードからまた7行くらい下に移動します。
目印は「invoke-virtual {v6, v4}, Landroid/view/View;->setVisibility(I)V」これ。
このあたり。この場合だと1191行目。

これの下に一行開けてまたコードを追記します。

    invoke-virtual {v7, v4}, Landroid/view/View;->setVisibility(I)V

    invoke-virtual {v8, v4}, Landroid/view/View;->setVisibility(I)V

これ。
これもまた1191行目「invoke-virtual {v6, v4}」の「v6」を基準に1ずつ加算していきます。
なので1191行目から続くコードは「v7」「v8」となる、と。

メニューボタンを常時表示させるための設定

アクションバーにメニューボタンが表示されたら右下のメニューボタンが消えるのを防ぐ、と。

まず1570行目あたり。
「.method public setMenuVisibility(Z)V」のあと。

これを下のように書き換える。

.method public setMenuVisibility(Z)V
	.locals 1
	.parameter "show"

	return-void
.end method

すげーすっきりするから不安になる。
続いてその下の「.method public setMenuVisibility(ZZ)V」のところ。

1画面に収まらないw
「.end method」までがこのセクション。

 

.method public setMenuVisibility(ZZ)V
    .locals 2
    .parameter "show"
    .parameter "force"

    .prologue
    .line 172
    if-nez p2, :cond_0

    iget-boolean v0, p0, Lcom/android/systemui/statusbar/phone/NavigationBarView;->mShowMenu:Z

    if-ne v0, p1, :cond_0

    .line 177
    :goto_0
    return-void

    .line 174
    :cond_0
    iput-boolean p1, p0, Lcom/android/systemui/statusbar/phone/NavigationBarView;->mShowMenu:Z

    .line 176
    invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/NavigationBarView;->getMenuButton()Landroid/view/View;

    move-result-object v1

    iget-boolean v0, p0, Lcom/android/systemui/statusbar/phone/NavigationBarView;->mShowMenu:Z

    if-eqz v0, :cond_1

    const/4 v0, 0x0

    :goto_1
    invoke-virtual {v1, v0}, Landroid/view/View;->setVisibility(I)V

    goto :goto_0

    :cond_1
    const/4 v0, 0x4

    goto :goto_1
.end method

こんなに長いこのセクションを下記のようにする。

.method public setMenuVisibility(ZZ)V
	.locals 2
	.parameter "show"
	.parameter "force"

	return-void
.end method

短すぎw。
これでメニューボタンが常に表示されるようになるんだと。

ナビゲーションバーにソフトキーを追加する。

いよいよ編集作業も終わりが見えてきた。長い。

「res/layout/navigation_bar.xml」をエディタで開く。

開いてみるとめまいがしそうになるくらいグワーッとコードが書いてあるのでヤル気が失せる。
けどじっくりとコードを眺めると、なんとなぁく意味が見えてくる気がする。

全体的な構成

ごちゃごちゃ書いてありますが、よく見ると理解できるようになるのかなと。
自分自身もコレを書きながら理解してます。

5行目「<FrameLayout>」から始まり23行目「</FrameLayout>」までがひとつのセクションであり、画面が回転しない、一番デフォルトの表示をどうするかについて定義している?のかなと。

その後、24行目からまた「<FrameLayout></FrameLayout>」でくくられたセクションが今度は画面が90度回転した時、つまり横画面にした時の表示をどうするかについて定義するんでしょう。

それでもってさらに「「<FrameLayout></FrameLayout>」の中に「<LinearLayout></LinearLayout>」セクションがありますが、

  • 最初の「<LinearLayout></LinearLayout>」は通常の場合。
  • 2回目の「<LinearLayout></LinearLayout>」はギャラリーやカメラといった特定のアプリの時の見え方

を意味してます。
ばっさりと書くと

<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.NavigationBarView
    <FrameLayout android:id="@id/rot0" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <LinearLayout android:orientation="horizontal" android:id="@id/nav_buttons"
		◆◆◆デフォルトの「横」画面のボタン配置◆◆◆
        </LinearLayout>
        <LinearLayout android:orientation="horizontal" android:id="@id/lights_out"
		◆◆◆特定のアプリの「横」画面のボタン配置◆◆◆
        </LinearLayout>
        <View android:layout_gravity="top" android:id="@id/deadzone"(よく分からん!)
    </FrameLayout>
    <FrameLayout android:id="@id/rot90"
        <LinearLayout android:orientation="vertical" android:id="@id/nav_buttons"
		◆◆◆デフォルトの「縦」画面のボタン配置◆◆◆
       </LinearLayout>
        <LinearLayout android:orientation="vertical" android:id="@id/lights_out"
		◆◆◆特定のアプリの「縦」画面のボタン配置◆◆◆
        </LinearLayout>
        <View android:layout_gravity="left" android:id="@id/deadzone"(よく分からん!)
    </FrameLayout>
    <View android:id="@id/rot270"(画面逆さまの設定?)
</com.android.systemui.statusbar.phone.NavigationBarView>

という構成。
◆◆◆のところだけ編集すれば、ボタンは配置できるはず。

 

さて1行ずつ見ていきますか。

脳内のひとりごとのように書いていきます。

2行目

<com.android.systemui.statusbar.phone.NavigationBarView android:background="#ff000000" android:layout_width="fill_parent" android:layout_height="fill_parent"

はナビゲーションバーの背景カラーを定義している気がする。
CSSくらいの知識しかないので、なんとなくです。はっきり言って。

「android:background=”#ff000000″」は背景色を「黒」とする定義?
「android:layout_width=”fill_parent” android:layout_height=”fill_parent”」は黒を縦幅、横幅いっぱいまで広げましょうということかな。

5行目

<FrameLayout android:id="@id/rot0" android:layout_width="fill_parent" android:layout_height="fill_parent">

「android:id=”@id/rot0″」というのはrotateつまり回転?のこと?つまるところ、一番デフォルトの画面設定かな。

6行目

<LinearLayout android:orientation="horizontal" android:id="@id/nav_buttons" android:clipChildren="false" android:clipToPadding="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animateLayoutChanges="true">

ここでの「android:clipChildren=”false”」「android:clipToPadding=”false”」

に詳しく書いてありました。
「・・・子の描画が」云々かんぬん書いてありますけど、リンク先の画像を見れば理解しやすいですね。
ここではいじる必要ないのかな、と。
ノータッチでスルー。

ナビゲーションバーのボタン配置

ここからが本題。
このナビゲーションバーに何をどう配置していくのか、という項目ですね。

このナビゲーションバーの幅が決まっていて、dipとかいうまたもやよく分からないもの。
最初の方に「dpi」が出てきたけど、それとどう違うの?よくわかりません。

に詳しく書いてあります。
もう理解が良く出来ないw

ということで無視。

元々のコードの中で「<LinearLayout></LinearLayout>」でくくられた中にwidthが何dipあるのか合計してみると320dipありました。
これに収まれば、いいんでない?というぐらいな安易な感じで行きます。

と思ったんだけど(あとでコンパイルしてみると)それではちょっと足りない。
RAZR iの横幅は540px。んでもってhdpi。
hdpiは基準となるmdpiの1.5倍だから逆に540pxを1.5で割ってしまうと360となる。
ということで360となるようにしたら上手く行きました。

まず7行目

<View android:visibility="invisible" android:layout_width="40.0dip" android:layout_height="fill_parent" android:layout_weight="0.0" />

これですが、android:visibility=”invisible”とあってその後のlayout_width=”40.0dip”とあります。
見えないけど40dip幅あるよ、ってこと?空白みたいな感じ?
元々のナビゲーションバーを見てみると左の方の無駄なく空白がそれに該当するのかなと思います。

8行目

これが「戻る」に該当する定義ですね。
ホントは1行だけど見やすいように改行しちゃった。良いのかどうか分からない。

<com.android.systemui.statusbar.policy.KeyButtonView
	android:id="@id/back"
	android:layout_width="80.0dip"
	android:layout_height="fill_parent"
	android:src="@drawable/ic_sysbar_back"
	android:layout_weight="0.0"
	android:contentDescription="@string/accessibility_back"
	systemui:keyCode="4"
	systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>

「android:id=”@id/back”」で「戻る」ボタンだよっていうラベルを貼る。
「android:layout_width=”80.0dip”」で幅は80dipだよ、と。
「android:layout_height=”fill_parent”」は具体的な高さの指定なし。埋め尽くし。
「android:src=”@drawable/ic_sysbar_back“」が使うべきアイコンを指定しているのかな?
だからもし自分でアイコンを作ってアイコン名もデフォルトとは違う場合はここでちゃんと指定する必要があると。
もう忘れかけてしまいましたが、最初に追加した時のアイコン名とあっているか見てもいいのかなと思います。

「systemui:glowBackground=”@drawable/ic_sysbar_highlight“」これがタッチした時の背景アイコンではないでしょうか。

あとのところは分からん!

こんな感じで見ていくと、

縦に

<view
<com
<view
<com
<view
<com
<com

と並んでいますよね。

これがボタン配置のデザインで、

<view・・・空白
<com・・・ボタン
<view・・・空白
<com・・・ボタン
<view・・・空白
<com・・・ボタン
<com・・・ボタン

ということなんでしょう。
このボタンを表す<com>の行を変えれば当然ボタンの位置も変わるし、<view>を消しちゃえば空白も消えると。
ただし、dipだけは気をつけて、320dipの幅を超えないように計算しておけばいいんでしょう。

ちょっと変なのは「メニューボタン」の記述

<com.android.systemui.statusbar.policy.KeyButtonView
	android:id="@id/menu"
	android:visibility="invisible"
	android:layout_width="40.0dip"
	android:layout_height="fill_parent"
	android:src="@drawable/ic_sysbar_menu"
	android:layout_weight="0.0"
	android:contentDescription="@string/accessibility_menu"
	systemui:keyCode="82"
	systemui:glowBackground="@drawable/ic_sysbar_highlight"
 />

あとは横画面にした時の設定を編集する。
縦画面のコードをそのままコピペすると、アイコンの指定がおかしいので画面が変になります。
ええ、1度変にしました。
横画面のアイコンには必ず「_land」が付きます。

それとwidthとheightの値も変わりますので注意。
横画面にした時、width=”fill_parent”、height=”数値dip”となります。

んで最終的に出来上がった「navigation_bar.xml」の値はこれです。

<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.NavigationBarView android:background="#ff000000" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <FrameLayout android:id="@id/rot0" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <LinearLayout android:orientation="horizontal" android:id="@id/nav_buttons" android:clipChildren="false" android:clipToPadding="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animateLayoutChanges="true">
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/search" android:layout_width="72.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_search" android:layout_weight="0.0" android:contentDescription="@string/accessibility_search" systemui:keyCode="84" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/back" android:layout_width="72.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_back" android:layout_weight="0.0" android:contentDescription="@string/accessibility_back" systemui:keyCode="4" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/home" android:layout_width="72.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_home" android:layout_weight="0.0" android:contentDescription="@string/accessibility_home" systemui:keyCode="3" systemui:keyRepeat="true" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/recent_apps" android:layout_width="72.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0.0" android:contentDescription="@string/accessibility_recent" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/menu" android:layout_width="72.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_menu" android:layout_weight="0.0" android:contentDescription="@string/accessibility_menu" systemui:keyCode="82" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" />
        </LinearLayout>
        <LinearLayout android:orientation="horizontal" android:id="@id/lights_out" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
            <ImageView android:layout_width="80.0dip" android:layout_height="fill_parent" android:layout_marginLeft="40.0dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0.0" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <ImageView android:layout_width="80.0dip" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0.0" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <ImageView android:layout_width="80.0dip" android:layout_height="fill_parent" android:layout_marginRight="40.0dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0.0" />
        </LinearLayout>
        <View android:layout_gravity="top" android:id="@id/deadzone" android:clickable="true" android:layout_width="fill_parent" android:layout_height="@dimen/navigation_bar_deadzone_size" />
    </FrameLayout>
    <FrameLayout android:id="@id/rot90" android:paddingTop="0.0dip" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <LinearLayout android:orientation="vertical" android:id="@id/nav_buttons" android:clipChildren="false" android:clipToPadding="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animateLayoutChanges="true">
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/menu" android:layout_width="fill_parent" android:layout_height="72.0dip" android:src="@drawable/ic_sysbar_menu_land" android:layout_weight="0.0" android:contentDescription="@string/accessibility_menu" systemui:keyCode="82" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/recent_apps" android:layout_width="fill_parent" android:layout_height="72.0dip" android:src="@drawable/ic_sysbar_recent_land" android:layout_weight="0.0" android:contentDescription="@string/accessibility_recent" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/home" android:layout_width="fill_parent" android:layout_height="72.0dip" android:src="@drawable/ic_sysbar_home_land" android:layout_weight="0.0" android:contentDescription="@string/accessibility_home" systemui:keyCode="3" systemui:keyRepeat="true" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/back" android:layout_width="fill_parent" android:layout_height="72.0dip" android:src="@drawable/ic_sysbar_back_land" android:layout_weight="0.0" android:contentDescription="@string/accessibility_back" systemui:keyCode="4" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/search" android:layout_width="fill_parent" android:layout_height="72.0dip" android:src="@drawable/ic_sysbar_search_land" android:layout_weight="0.0" android:contentDescription="@string/accessibility_search" systemui:keyCode="84" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" />
        </LinearLayout>
        <LinearLayout android:orientation="vertical" android:id="@id/lights_out" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
            <ImageView android:layout_width="fill_parent" android:layout_height="80.0dip" android:layout_marginTop="40.0dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0.0" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <ImageView android:layout_width="fill_parent" android:layout_height="80.0dip" android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0.0" />
            <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <ImageView android:layout_width="fill_parent" android:layout_height="80.0dip" android:layout_marginBottom="40.0dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0.0" />
        </LinearLayout>
        <View android:layout_gravity="left" android:id="@id/deadzone" android:clickable="true" android:layout_width="@dimen/navigation_bar_deadzone_size" android:layout_height="fill_parent" />
    </FrameLayout>
    <View android:id="@id/rot270" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</com.android.systemui.statusbar.phone.NavigationBarView>

特定のアプリの際の設定は特に変えてません。あまり使うこともないし。

コンパイル

さあもとに戻しましょう。
いよいよです。

最初の最初でやったScript.batを起動。プロジェクトを開いてください。

最初に圧縮レベルを変更します。

-----------
tools Stuff
-----------
21   Select compression level for apk's
-------------------------------------------------------------------------------
lease make your decision:21
Enter Compression Level (0-9) : 0

apkへファイルを戻す場合、圧縮率はゼロでないとダメなのでその設定ですね。

次にいよいよコンパイルです。
「11」を選んでコンパイルすると。

------------------------------------
 Advanced Tasks Such As Code Editing
------------------------------------
 11   Compile System APK files
-------------------------------------------------------------------------------
lease make your decision:11

エラーが出なければこんな感じで進んでいきます。

Building Apk
Aside from the signatures, would you like to copy
over any additional files that you didn't modify
from the original apk in order to ensure least
# of errors (y/n)
Type input: y

「Type input:」と表示されたら「y」YESを入力、エンター。

ずらずらと解凍が始まる。

Extracting  res\menu\recent_popup_menu.xml
Extracting  res\raw\carousel.bc

Everything is Ok

Files: 1415
Size:       2366314
Compressed: 1946407
In the APK Multi-Tools folder u'll find
a keep folder. Within it, delete
everything you have modified and leave
files that you haven't. If you have modified
any xml, then delete resources.arsc from that
folder as well. Once done then press enter
on this script.

ここまで来たら、すぐにエンターを押さないで、「keep」フォルダを確認する。

このフォルダ内のものはデフォルトのファイルでこれらを消さない場合、それをそのままコンパイルしちゃうよ、と。
だから逆に言えば手を加えたものは消さないとダメみたいですね。
ということで「res」フォルダごと(画像とか)、「classes.dex」(smaliとか)「resources.arsc」(なんとか.xmlとか)を消します。

それでまたDOS窓に戻ってエンター。
マシンの性能がそこそこあれば一瞬で元のメイン画面に戻ります。
「\APK-Multi-Tool\place-apk-here-for-modding」フォルダ内に「System_SystemUI.apk」があればオッケー。

さあ、システムファイルを書き換えます。

rootexplore等でGUI的に書き換えてもいいですけど、SystemUI.apkの上書きが出来ないので、コマンドを打ち込んで行きました。
基本、Ubuntuでの作業ですがadbコマンドとかはほぼ一緒ですからWindowsでもいけるかな。

 

$ ls(ディレクトリ内のファイルを表示)
SystemUI-5buttons.apk
$ adb devices(adb接続できているか確認)
List of devices attached 
TA23701UV2	device
$ adb push SystemUI-5buttons.apk /sdcard/ (ファイルを端末内の/sdcard/ディレクトリへコピー)
5099 KB/s (1946407 bytes in 0.372s)
$ adb shell(android内のbusyboxから操作します)
$ su(SuperUser権限を取得)
# mount -o remount,rw /dev/block/mtdblock0 /system(読み取り専用の/system以下をマウント)
# cp /sdcard/SystemUI-5buttons.apk /system/app/(apkをSDカードから/system/appへコピー。)
# cd /system/app(自分も/system/appへ移動)
# cp SystemUI.apk SystemUI.apk.bak(元々のSystmUI.apkのバックアップをとっておく)
# chmod 644 SystemUI-5buttons.apk(permissionの書き換え)
# chown root SystemUI-5buttons.apk(所有者の書き換え)
# mv SystemUI-5buttons.apk SystemUI.apk(SystemUI.apkへ上書き)
# mv SystemUI.odex SystemUI.odex.bak(バックアップ)
# reboot(再起動)

再起動。

さてどうなるか。

お、アップグレードだ!

そして無事に書き換えができていますね。

ふえぇー疲れたー。
コンパイル自体何度もやってようやくここまでこれました。

自分はデベロッパではないので、詳しい理屈とかよく分かりません。
すみません。

もし失敗したら、バックアップを取ったSystemUI.apk.bakをSystemUI.apkと書き換え上書きしちゃえば大丈夫。
起動さえしていれば、adbモードが動きますから深刻なエラーになることはないと思うんだけど。

booleeをフォローする
BOOLEE STREET.net

コメント