おすすめの実装

折りたたみ式デバイスとマルチスクリーン デバイス対応のアプリ

アプリは通常、静的 ID、または一部のディスプレイ ID に依存するロジックを使用することはありません。ほとんどの場合、アプリはサイズ変更してさまざまなディスプレイで動作する必要があり、システムはアプリの場所を制御する必要があります。その目的は、折りたたみ式デバイスで新しいユニークなエクスペリエンスを実現したり、折りたたまれたデバイスの外側の画面で特別なアプリを起動したりすることです。

この場合、SystemUI または他のシステム コンポーネントは折りたたみの状態を検出し、アクションの実行に適しているかどうかを判断してからターゲット アクティビティを開始して、外側のディスプレイ ID を起動ターゲットとして指定する必要があります。アプリはこのアクションを検出することも、これに応じたアクションを実行して特定のディスプレイで起動することもできません。つまり、1 台のデバイスで動作するからといって他のデバイスでも動作するとは限らないということです。要するに、デバイス固有のコードによって断片化が増加します。

ディスプレイへのアクセスの制限

デバイス設定で 1 つ以上のディスプレイへのアクセスを制限する必要がある場合は、Display#FLAG_PRIVATE フラグを使用して、該当するディスプレイを非公開に指定することをおすすめします。これにより、所有者以外はそのディスプレイにコンテンツを追加できなくなります。所有者以外のユーザーが、アクティビティを開始したりウィンドウを追加したりしようとすると、SecurityException が発生します。ディスプレイの所有権がシステムにある場合、システムはウィンドウを追加してアクティビティを開始できます。

さらに、ディスプレイに配置されたエンティティは常にそのディスプレイにアクセスできます。 所有者によってディスプレイで起動されたアクティビティは、同じディスプレイで他のアクティビティを起動できます。そのため、所有者はアクセスを制限して、信頼できるアプリのみを許可する必要があります。

また、仮想ディスプレイはあらゆるアプリがユーザーに表示せずに作成できるため、制限が追加されています。仮想ディスプレイの所有権がシステムにない場合、allowEmbedded によるアクティビティのみが許可され、呼び出し元には ACTIVITY_EMBEDDING 権限が必要です。

詳しくは以下をご覧ください。

  • ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
  • ActivityDisplay#isUidPresent()
  • DisplayManagerService#isUidPresentOnDisplay()

アクティビティの起動を条件付きで制御するには、LaunchParamsController を使用してすべてのアクティビティの起動を阻止し、起動に使用されるパラメータをシステム コンポーネントが変更できるようにします。これは system_server で使用できます。

ディスプレイのウィンドウ環境とシステム デコレーションの設定

システム デコレーションは、DisplayWindowSettings でディスプレイごとに設定できます。デバイスの実装では、/data/system/display_settings.xml でデフォルトの設定を提供できます。

この値は、ディスプレイにシステム デコレーション(ランチャー、壁紙、ナビゲーション バーなどのデコレーション ウィンドウ)と IME を表示するかどうかを決定します。詳しくは、DisplayWindowSettings#shouldShowSystemDecorsLocked()DisplayWindowSettings#shouldShowImeLocked() をご覧ください。

ディスプレイを識別するために、一意の ID(デフォルトでは DisplayInfo#uniqueId が使用される)またはハードウェア ディスプレイの物理ポート ID(DisplayInfo#address を参照)を使用します。

たとえば、次のディスプレイの設定例では、シミュレーション ディスプレイでシステム デコレーションと IME が有効化されます。

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="0" />
<display
  name="overlay:1"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

上記の例では、name 属性の uniqueId がディスプレイの識別に使用されます(シミュレーション ディスプレイは overlay:1)。内蔵ディスプレイの場合、サンプル値は "local:45354385242535243453" の可能性があります。 ハードウェアのポート情報を使用して DisplayWindowSettings#IDENTIFIER_PORT に対応する identifier="1" を設定し、"port:<port_id>" 形式を使用するように名前を更新することもできます。

<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="1" />
<display
  name="port:12345"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

詳しくは、静的ディスプレイ ID をご覧ください。

詳しくは以下をご覧ください。