ドックモードの強制(ルートを使用)

はじめに



少し前まで、リリースされたGalaxy S3は、アクセサリーの分野における他の革新の中でも、新しい、ひどく退屈な車のドックを受け取りました。 回線の以前のデバイス(S、S2、注)とは異なり、このデバイスは「ユニバーサル」になっているため、特別な抵抗器がなく、電話を強制的にカーモードに切り替えました。 そして、最初のSGSに本格的なドッキングステーションを使用していた人として、ドックにインストールするとスピーカーフォンモードがオンになり、TouchWizの横向きが表示されることにすでに慣れています。 しかし、これは新しいドックでは達成できませんでした...



しかし、解決策が見つかりましたが、必要なのは1つのNFCタグ、ルート、および数時間の検索とプログラミングだけでした。



ソリューションを検索する



この「ユニバーサル」ドックを持っていなくても、最初にしたことは、最初のSGSからドッキングステーションを分解することでした。 結果は私が望んでいたものにかなり近かったが、かなりおかしいように見えた:







この写真は、通知領域で「車」アイコンがひらめいていることを示しています。したがって、運転モード(S-Voice)とは関係ありません。これはAndroid自体からの通知です。



しかし、SGSとそのドックの両方を返却する必要があり、その後新しいドックが私のところに来て、体制を切り替えるという問題が完全な成長の中で生じました。 明らかな解決策は、NFCタグを使用してカーモードをオンにすることでしたが、これを実現する方法は? Google Playには、おそらくCar Modeを含むアプリケーションがありますが、実際にはCar Homeを起動するだけの標準のUiModeManagerメソッドを使用しており、スピーカーフォンと私が望む方向はあまり含まれていません。







Androidのドキュメントには、デバイスがドックにあるかどうか判断するための標準的な方法があります。

registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT)).getIntExtra(Intent.EXTRA_DOCK_STATE, -1);
      
      





また、この状態を示すメソッドについても説明します。

 sendStickyBroadcast((new Intent(Intent.ACTION_DOCK_EVENT)).putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_CAR));
      
      





ただし、実際のプログラムでは機能しません。 具体的には、このイベントには特別な権限が必要です(実際、USBコントローラーによって生成されます)。 しかし、ルートであっても、これをどのように行うことができますか?



シンプルでかなり有名なソリューションがあります:

 su -c /system/bin/am broadcast -a android.intent.action.DOCK_EVENT --ei android.intent.extra.DOCK_STATE 2
      
      





残念ながら、これは不完全です。 はい、この呼び出しは完全なカーモードを正常にオンにしますが、「スティッキー」ではなく通常のブロードキャストであるため(amユーティリティはこれを行う方法を知りません)、前述のドッキングステーションのステータスを決定する方法は機能しないため、開始する必要がありますアプリケーションには2つのボタン(「オン」と「オフ」)があるか、本格的なシステムメッセージを送信する方法があります。



Androidソースを少し調べてみると 、このメッセージを送信しているDockObserverクラスを見つけることができます。 調べてみると、実際には、モードの変更(たとえば、ドックへの挿入音を再生する)を通知するだけでなく、特別なイベント(UEvent)が到着したときに何をするかだけではありません。 つまり、そのようなイベントを作成することを学べば、効果だけでなく原因も模倣できます!



まあ、これはNDKを使用してかなり簡単なコードで行われます:



 char event[] = "ACTION=change\0DEVPATH=/devices/virtual/switch/dock\0SUBSYSTEM=switch\0SWITCH_NAME=state\0SWITCH_STATE=2"; int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (sock != -1) { struct sockaddr_nl snl; struct iovec iov = { event, sizeof(event) }; struct msghdr msg = { &snl, sizeof(snl), &iov, 1, NULL, 0, 0 }; memset(&snl, 0, sizeof(struct sockaddr_nl)); snl.nl_family = AF_NETLINK; snl.nl_pid = getpid(); snl.nl_groups = -1; sendmsg(sock, &msg, 0); close(sock); }
      
      





このユーティリティを、上記の標準的な方法で現在の状態を読み取り、ルートの下からコンソール呼び出しで切り替えるアプリケーションにパックするだけです。



おわりに



そのため、アプリケーション自体はGoogle Playで利用できます(今ではストアから何らかの形で削除されていますが、 .apkファイルをダウンロードできます )。

起動時に電話をカーモードに切り替え、再起動時に電話を終了します。

NFCタグにその発射を掛けると、非常に本格的なカードックを入手できます。



さて、すべてのソースはGitHubにあります



All Articles