LoginSignup
0
1

More than 5 years have passed since last update.

Android Kitkat 4.4.2〜4.4.4向けAppOpsの移植

Posted at

アプリの権限操作。

今更Kitkatである。しかしアプリ権限操作は重要な機能なので纏めておく。

Androidに公式のアプリ権限機能が Jerry Beans 4.3に搭載された。
これがApp Opsである。しかしこの時点では隠し機能であり、ショートカットアプリから呼び出すことができる。
4.4.1まではこの隠し機能へショートカットのみでアクセスすることができていたのだが、
4.4.2からはショートカットだけではアクセスできなくされてしまった。
スラドの記事によると、App OpsはGoogleが誤って公開してしまった実験段階の機能であるらしい。

しかしApp Ops自体は4.4.2〜4.4.4にも残っており、設定アプリを少し弄るとこれを復活させることができる。

…カスタムロム等を使用している場合は最初からこの機能へのアクセスを可能にしている場合がある。
一度設定アプリを隅々まで探索し、App Ops機能が無いことを確認してから実験に移ることを推奨する。
筆者の環境はCM11(4.4.4)だったのだが、この記事を書き終える直前に設定アプリからプライバシー→プライバシーガード→メニュー→詳細設定でApp Opsが起動できることを確認した。
骨折り損のくたびれ儲けにならぬよう。

早速Settings.apkを弄る。

こちらのWebページが非常に参考になる。というよりこの記事は大半翻訳しただけ…。
4.4.2とあるが、4.4.3、4.4.4でも同様の手順で対応可能なようだ。

用意するもの

  1. apktool
  2. Settings.apk
  3. framework-res.apk

apktoolはJava1.7が必要になるので各自インストールすること。
ここではLinuxで実験したのでコマンドもbash向けであるが、他のプラットフォームでもほとんど変わらず実行できるはずだ。
2と3に関しては端末によっては名前が違ったり、おいてある場所が違ったり、3の場合は複数存在したりすることもあるので注意。といってもバリバリにカスタムロムを作っている方たちならば問題ないはずだ。
当然だが問題が起こった時のためにバックアップは確実にとっておくこと。
筆者の環境ではSettings.apkは/system/priv-appに、framework-res.apkは/system/frameworkにあった。
異なっていた場合は当然以下の手順も適宜置き換えて考えるように。

手順1.Settings.apkをデコンパイルする

上記の3つを取り出したら同じディレクトリに置き、以下のコマンドを実行する。

$ ./apktool if framework-res.apk
$ ./apktool d Settings.apk
$ mv Settings.apk Settings_bak.apk

これでSettings.apkが展開される。
一行目は無くてもデコンパイルできることが多いが、無しでデコンパイルすると再度コンパイルできないので必ずデコンパイルする前に実行しておく。

手順2.Settings.smaliの編集・一箇所目

16進数の値は環境によって違うはずなので気にする必要はない。

Settings.smali
(省略)
.method static constructor <clinit>()V
    .locals 3

    .prologue
    const/4 v2, 0x0

    .line 170
    sput-boolean v2, Lcom/android/settings/Settings;->sShowNoHomeNotice:Z

    .line 435
    const/16 v0, 0x3b

    new-array v0, v0, [Ljava/lang/String;
(省略)

sput-boolean v2, Lcom/android/settings/Settings;->sShowNoHomeNotice:Zで検索をかけるとすぐに場所がわかると思われる。

余談だが、Bashでファイルの中まで検索をかけたい場合は以下のコマンドを実行すれば良い。
Settings.smaliというファイルが無いときはこれで探すことができる。
以降の手順もファイルがない、あってもそのファイルに該当する箇所がないケースも少なくないので覚えておくと良い。

$ grep -rnw . -e "sput-boolean v2, Lcom/android/settings/Settings;->sShowNoHome
Notice:Z"

さて、今回の修正で重要なのはconst/16 v0, 0xXXXXの値だ。
この値に1を加算する。
当然16進数なので16進数で計算するように。

Settings.smali
(省略)
.method static constructor <clinit>()V
    .locals 3

    .prologue
    const/4 v2, 0x0

    .line 170
    sput-boolean v2, Lcom/android/settings/Settings;->sShowNoHomeNotice:Z

    .line 435
    const/16 v0, 0x3c

    new-array v0, v0, [Ljava/lang/String;
(省略)

このような感じだ。const/16 v0, 0x3bconst/16 v0, 0x3cに修正している。
数字は環境によって異なるが、とにかく1を加算すれば良い。

手順3.Settings.smaliの編集・二箇所目

Settings.smali
    const/16 v1, 0x2b

    const-class v2, Lcom/android/settings/inputmethod/KeyboardLayoutPickerFragment;

    invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String;

    move-result-object v2

    aput-object v2, v0, v1

    const/16 v1, 0x2c

const-class v2, Lcom/android/settings/inputmethod/KeyboardLayoutPickerFragment;で検索をかけると出てくると思われる。
aput-object v2, v0, v1の後(筆者の環境ではその下のconst/16 v1, 0x2cとの間)に

    const/16 v1, 0x3b

    const-class v2, Lcom/android/settings/applications/AppOpsSummary;

    invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String;

    move-result-object v2

    aput-object v2, v0, v1

を追記する。とにかくaput-object v2, v0, v1の後であればよい。
この時、一行目のconst/16 v1, 0xXXXX一箇所目の編集箇所の編集前の値を入れる。
今回の例では一箇所目を0x3bから0x3cに修正したのでここに入る値は0x3bとなる。

Settings.smali
    const/16 v1, 0x2b

    const-class v2, Lcom/android/settings/inputmethod/KeyboardLayoutPickerFragment;

    invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String;

    move-result-object v2

    aput-object v2, v0, v1

    const/16 v1, 0x3b

    const-class v2, Lcom/android/settings/applications/AppOpsSummary;

    invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String;

    move-result-object v2

    aput-object v2, v0, v1

    const/16 v1, 0x2c

このようになるはずだ。

手順4.values/strings.xmlの編集

<string name="app_ops_settings_summary">Manage app permissions</string>

</resources>の一行手前あたりに追記すれば良い。

手順5. xml/security_settings_misc.xmlの編集

追記する内容は

<Preference android:title="@string/app_ops_settings" android:key="app_ops_summary" android:summary="@string/app_ops_settings_summary" android:fragment="com.android.settings.applications.AppOpsSummary" />

これをdevice admin titleの後に追記する。
…なのだが筆者の環境にはsecurity_settings_misc.xmlはなかった。
こういう時は手順2で解説した

$ grep -rnw . -e "device admin"

を使う。
するとsecurity_settings.xmlのみが候補に上がった。

security_settings.xml
(省略)
    <PreferenceCategory android:persistent="false" android:title="@string/device_admin_title" android:key="device_admin_category">
        <Preference android:persistent="false" android:title="@string/manage_device_admin" android:summary="@string/manage_device_admin_summary" android:fragment="com.android.settings.DeviceAdminSettings" />
        <CheckBoxPreference android:persistent="false" android:title="@string/install_applications" android:key="toggle_install_applications" android:summaryOn="@string/install_unknown_applications" android:summaryOff="@string/install_unknown_applications" />
(省略)

とあるので、

        <Preference android:persistent="false" android:title="@string/manage_device_admin" android:summary="@string/manage_device_admin_summary" android:fragment="com.android.settings.DeviceAdminSettings" />`

の後に

        <Preference android:title="@string/app_ops_settings" android:key="app_ops_summary" android:summary="@string/app_ops_settings_summary" android:fragment="com.android.settings.applications.AppOpsSummary" />

を追記すれば良い。

security_settings.xml
(省略)
    <PreferenceCategory android:persistent="false" android:title="@string/device_admin_title" android:key="device_admin_category">
        <Preference android:persistent="false" android:title="@string/manage_device_admin" android:summary="@string/manage_device_admin_summary" android:fragment="com.android.settings.DeviceAdminSettings" />
        <Preference android:title="@string/app_ops_settings" android:key="app_ops_summary" android:summary="@string/app_ops_settings_summary" android:fragment="com.android.settings.applications.AppOpsSummary" />
        <CheckBoxPreference android:persistent="false" android:title="@string/install_applications" android:key="toggle_install_applications" android:summaryOn="@string/install_unknown_applications" android:summaryOff="@string/install_unknown_applications" />
(省略)

手順6.Settings.apkをコンパイルする

以下のコマンドを実行する。

$ ./apktool b -c Settings -o Settings.apk

うまくデコンパイル・編集ができていればビルドに成功するはずだ。
後は元のSettings.apkと置き換えれば完了。
今回の例だと設定→セキュリティ→アプリの操作状況でApp Opsを起動できるようになっている。

他のAndroidバージョンでのアプリ権限操作

余談だが、Android Lollipop 5には最初から権限操作機能ついているらしい。これについては情報が少なく、筆者にもよくわかっていない。
Android Marshmallow 6以降はアプリが権限を要求した段階でユーザーに権限を渡してよいか尋ねられる仕組みになった。

他にもRoot化端末向けにはXposedのモジュールにXPrivacyというものがある。これもアプリが権限を要求した段階でユーザーに権限を渡してよいか尋ねられる仕組みだが、Android6以降の公式権限管理機能よりも細かい調整が可能になっている。
これはRoot化されており、Xposedがインストール済みの環境ならばAndroid 4.2.2以下でも使用可能だ。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1