【root不要】Xiaomi HyperOSで電源ボタン2回押しからGCamを起動する方法

概要

XiaomiのHyperOSでは、電源ボタンを2回押すと標準カメラが起動します。これをGCamが起動するように変更したかったのですが、どうやら設定から変えることはできないらしい。

今回は、HyperOS内部に存在するMi Pay起動機能と、オープンソースの「HyperOS Wallet Shortcut」を利用し、電源ボタン2回押しからGCamを起動できるようにしてみました。

改造APKは呼び出されたときだけ起動し、GCamへ転送して終了するだけなので、何も常駐させる必要はありません。

ロック画面からの起動もできます。

動作確認環境

項目環境
端末Xiaomi 13T
OSHyperOS 2.0.16.0
Android15
GCamMGC 9.4.103
GCamパッケージ名org.codeaurora.snapcam
PCWindows / PowerShell
root不要
Shizuku不要
Android Studio不要

GCamパッケージ名とはこれのこと。一番上の、org.codeaurora.snapcam 以外を入れた場合は随時置き換えてください。

https://www.celsoazevedo.com/files/android/google-camera/dev-bsg/f/dl329

1. 仕組み

HyperOSには、電源ボタン2回押しでMi Payを起動するための内部設定が存在する。

通常のカメラ起動設定は以下。

double_click_power_key = launch_camera

これを、

double_click_power_key = mi_pay

に変更すると、HyperOSはMi Payを起動しようとする。しかし、グローバル版ROMにはそもそもMi Payアプリ自体が入っていない。

ここで、Mi Payと同じパッケージ名 com.miui.tsmclient を持つ別のアプリをインストールすることで、Mi Payの代わりにそのアプリを起動させられる。
(グローバル版ROMでもMi Payを呼び出すための mi_pay 処理がOS内部に残っていることを利用している)

利用したのは、Google Walletを起動するために開発された「HyperOS Wallet Shortcut」。

このアプリの起動先をGoogle WalletからGCamに書き換える。

2. 必要なツール

PCに以下を用意する。

  • ADB(Android Debug Bridge)
  • Java(JDK 17など)
  • Apktool
  • Uber APK Signer
  • HyperOS Wallet Shortcut v1.2.1 APK

ダウンロード先:

ADBはインストール済みでPATHが通っていることを前提とする。

Javaがインストールされていない場合、PowerShellで以下を実行する。

winget install EclipseAdoptium.Temurin.17.JDK

Javaが使えるか確認する。

java -version

今回はDownloadsフォルダを作業ディレクトリとして使用する。

cd "$HOME\Downloads"

以下の3ファイルを配置する。

HyperOS-Wallet-Shortcut-v1.2.1.apk
apktool.jar
signer.jar

ApktoolとUber APK Signerは、ダウンロードしたJARファイルをそれぞれ apktool.jar と signer.jar にリネームする。

実際に動作確認したバージョンは、Apktool 3.0.3、Uber APK Signer 1.3.0。

3. Mi Payの起動機能を有効化する

スマートフォン側で開発者向けオプションを有効化し、USBデバッグを許可する。

PCとUSB接続し、ADBが使える状態にする。

adb devices

端末が認識されていることを確認する。

まず、現在の電源ボタン2回押しの設定を確認。

adb shell settings get system double_click_power_key

初期状態では以下が返ってきた。

launch_camera

次に、本物のMi Payがインストールされていないことを確認する。

adb shell pm list packages -u com.miui.tsmclient

何も表示されなければ、同じパッケージ名を使う転送アプリをインストールできる可能性がある。

続いて、電源ボタン2回押しをMi Payに変更する。

adb shell settings put system double_click_power_key mi_pay

WRITE_SETTINGSで拒否された場合

今回のHyperOSでは、最初に以下のエラーが発生した。

java.lang.SecurityException:
com.android.shell was not granted this permission:
android.permission.WRITE_SETTINGS

ADBのshellユーザーに対して設定変更操作が許可されていなかったため、AppOpsを変更した。

adb shell appops set com.android.shell WRITE_SETTINGS allow

その後、再度実行。

adb shell settings put system double_click_power_key mi_pay

確認。

adb shell settings get system double_click_power_key

以下が返ってくれば成功。

mi_pay

今回はShizukuを使用せず、ADBだけで設定できた。

4. HyperOS Wallet Shortcutの動作確認

まず、ダウンロードしたオリジナルAPKをインストールする。

adb install .\HyperOS-Wallet-Shortcut-v1.2.1.apk

電源ボタンを2回押して、Google Walletが起動することを確認する。

今回のXiaomi 13Tでは正常に起動した。

これによって、mi_pay に割り当てたショートカットが、com.miui.tsmclient のアプリを起動することが確認できた。

以降は、このAPKの起動先をGCamに変更する。

5. GCamのパッケージ名を確認する

インストール済みのGCamのパッケージ名を調べる。

adb shell pm list packages -3 | Select-String 'mgc|gcam|snapcam|camera'

今回の結果は以下。

package:org.codeaurora.snapcam

GCamのAPKによってパッケージ名は異なるため、別のGCamを使用している場合は適宜読み替える。

6. APKを展開する

作業ディレクトリに移動する。

cd "$HOME\Downloads"

ApktoolでAPKを展開。

java -jar .\apktool.jar d .\HyperOS-Wallet-Shortcut-v1.2.1.apk -o .\wallet-work

展開すると、wallet-work ディレクトリが作成される。

今回変更するのは主に以下の2ファイル。

wallet-work\smali\com\miui\tsmclient\WalletLauncher.smali

wallet-work\AndroidManifest.xml

Smaliは、AndroidのDEXバイトコードをテキスト形式で表したもの。Javaのソースコードがなくても、ここを書き換えて再構築できる。

7. GCam起動用に改造する

PowerShellで以下を実行する。

このスクリプトでは、ロック解除中とロック中の両方に対応するため、3つの文字列を置換する。

$smali = (Resolve-Path ".\wallet-work\smali\com\miui\tsmclient\WalletLauncher.smali").Path
$manifest = (Resolve-Path ".\wallet-work\AndroidManifest.xml").Path

$utf8 = [System.Text.UTF8Encoding]::new($false)

# Smaliを読み込み
$s = [System.IO.File]::ReadAllText($smali)

# Google Walletのパッケージ名をGCamへ変更
$s = $s.Replace(
    "com.google.android.apps.walletnfcrel",
    "org.codeaurora.snapcam"
)

# ロック解除中の起動先Activityを変更
$s = $s.Replace(
    "com.google.commerce.tapandpay.android.wallet.WalletActivity",
    "com.android.camera.CameraLauncher"
)

# ロック中の起動Intentを変更
$s = $s.Replace(
    "com.google.android.apps.wallet.main.QUICKDRAW",
    "android.media.action.STILL_IMAGE_CAMERA_SECURE"
)

# 保存
[System.IO.File]::WriteAllText($smali, $s, $utf8)

# AndroidManifest.xmlも変更
$m = [System.IO.File]::ReadAllText($manifest)

$m = $m.Replace(
    "com.google.android.apps.walletnfcrel",
    "org.codeaurora.snapcam"
)

[System.IO.File]::WriteAllText($manifest, $m, $utf8)

ここで重要なのは、ロック中の起動Intentに指定した以下の文字列。

android.media.action.STILL_IMAGE_CAMERA_SECURE

これはAndroid標準のロック画面用カメラ起動Intent。

当初、この部分を変更せずに試したところ、ロック解除中はGCamが起動したものの、ロック中には起動しなかった。

Google Wallet専用の QUICKDRAW を、カメラ用の STILL_IMAGE_CAMERA_SECURE に変更することで解決した。

なお、APK自身のパッケージ名 com.miui.tsmclient は変更しない。HyperOSにMi Payとして起動させるために必要。

8. APKを再構築する

Apktoolで再ビルドする。

java -jar .\apktool.jar b .\wallet-work -o .\gcam-lock-unsigned.apk

成功すると次のように表示される。

I: Smaling smali folder into classes.dex...
I: Building resources with aapt2...
I: Building apk file...
I: Built apk into: .\gcam-lock-unsigned.apk

9. APKを再署名する

APKは改造すると元の電子署名が無効になるため、署名し直す必要がある。

Uber APK Signerを使って署名する。

java -jar .\signer.jar -a .\gcam-lock-unsigned.apk

正常なら、次のように表示される。

- zipalign success
- sign success
- zipalign verified
- signature verified [v1, v2, v3]
Successfully processed 1 APKs and 0 errors

今回の出力ファイル名は以下。

gcam-lock-aligned-debugSigned.apk

10. 改造APKをインストールする

オリジナル版とは署名が異なるため、先にアンインストールする。

adb uninstall com.miui.tsmclient

続いて、改造版をインストール。

adb install .\gcam-lock-aligned-debugSigned.apk

Success と返ればインストール完了。

double_click_power_key は既に mi_pay に設定されているため、通常は再設定不要。

11. ロック画面での起動を許可する

HyperOSでは、アプリごとにロック画面への表示権限が制御されている。

今回、GCamはSecure Camera用のActivityを起動できていたものの、権限がない状態ではロック画面の裏側に隠れていた。

そのため、スマートフォンの設定から以下を変更する。

  1. 設定 → アプリ → アプリを管理
  2. GCamを選択
  3. その他の権限
  4. 「ロック画面に表示」を許可

設定項目が存在する場合、「バックグラウンドで新しいウィンドウを開く」も許可する。

ロック中の動作確認

ADBから直接GCamのセキュアカメラを起動して確認できる。

adb shell am force-stop org.codeaurora.snapcam

adb shell am start -W -a android.media.action.STILL_IMAGE_CAMERA_SECURE -p org.codeaurora.snapcam

今回の起動成功ログは以下。

Status: ok
LaunchState: COLD
Activity: org.codeaurora.snapcam/com.google.android.apps.camera.legacy.app.activity.SecureCameraActivity

なお、Status: ok だけでは実際に画面に表示できたとは限らない。端末上でロック解除なしにカメラが表示されることを確認する。

12. 動作確認結果

最終的に以下の動作が確認できた。

状態電源ボタン2回押し
ロック解除中GCam起動成功
ロック中GCam起動成功
root権限不要
Shizuku不要
PC常時接続不要

通常時は com.android.camera.CameraLauncher を、ロック時は STILL_IMAGE_CAMERA_SECURE に対応するActivityを起動している。

電源ボタンの監視アプリを常駐させる必要もない。

13. 元に戻す方法

標準カメラに戻したい場合は、ADBで以下を実行する。

adb shell settings put system double_click_power_key launch_camera

確認。

adb shell settings get system double_click_power_key

launch_camera と表示されれば元の割り当てに戻っている。

改造APKも不要ならアンインストールする。

adb uninstall com.miui.tsmclient

また、ADBのshellユーザーに付与したAppOpsの設定を元に戻す場合は、初期状態が default であったことを確認したうえで以下を実行する。

adb shell appops set com.android.shell WRITE_SETTINGS default

注意事項

  • Mi Payが実際にインストールされている端末では、この方法をそのまま利用できない。
  • HyperOSのアップデートによって内部の mi_pay 起動処理が変更される可能性がある。
  • 端末再起動時に double_click_power_key がリセットされる場合がある。その場合は再設定が必要。
  • 今回の改造版は独自の署名を使用しているため、公式のWallet Shortcut APKをそのまま上書きインストールすることはできない。
  • GCamのパッケージ名やActivityはAPKによって異なる。
  • ロック中のカメラ起動と、端末ロックの解除は別の処理。撮影済み写真へのアクセスなどは、GCamの実装とAndroidの権限管理に依存する。

まとめ

今回の方法は、HyperOSの内部機能である mi_pay を利用し、Mi Payと同じパッケージ名を持つアプリを経由してGCamを起動するもの。

OS本体の改造やroot権限は必要なく、ADBによる設定変更と、既存APKのSmali改造だけで実現できた。

特にロック画面からの起動では、Android標準の STILL_IMAGE_CAMERA_SECURE Intentと、HyperOS側の「ロック画面に表示」権限の両方が重要だった。

Xiaomi 13T / HyperOS 2.0.16.0 / Android 15において、ロック状態を含む電源ボタン2回押しからのGCam起動に成功した。


参考資料:

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

→ Index