Android 12で導入されたLetterboxingについて
Letterboxingについて
Android 12から追加された機能です。
デバイスの画面サイズに最適化されていないアプリを、画面中央などに配置して余白を黒く塗りつぶし表示します。
これにより、例えばユーザーは縦画面固定のアプリをタブレット上で横画面のまま操作できます。
公式ドキュメントはこちらです
下記は、公式ドキュメントに掲載されている表示例です。
どのような条件・デバイスでLetterboxing表示になるのか?
「特定条件を満たしたアプリ」を「特定のデバイス」で実行すると、Letterboxing表示になります。
特定条件を満たしたアプリとは?
https://developer.android.com/guide/practices/device-compatibility-mode#issue に詳細な記述がありますが、下記の どれか一つでも 満たしたアプリです。
- Activityの向きを固定している
- Activityのアスペクト比が固定
- Activityのリサイズに未対応
例えば良くあるパターンだと、
- 横画面レイアウトでのデザインコスト削減のため、Activityの向きを縦画面に固定しているアプリ
- Configuration change対応の実装コスト削減のため、Activityの向きを縦画面に固定しているアプリ
などがあるでしょう。
特定のデバイスとは?
Android 12以上を搭載した大画面デバイス(タブレット、フォルダブル)です。
ただし、上記のデバイスで常に「特定条件を満たしたアプリ」がLetterboxing表示になるわけではありません。
Letterboxing表示にするかどうかは端末メーカーが決める事なので、Android 12以上でもLetterboxing表示にならない端末は存在します。
Google製の大画面デバイスではLetterboxing表示になるので、下記で実機動作を確認出来ます。
- Pixel Tablet
- Pixel Fold
- Pixel 9 Pro Fold
フォルダブル端末は、メイン画面(大きな画面)でのみ、Letterboxing表示となります。
また、エミュレーターでも確認可能です。
Letterboxingを回避するには?
先に挙げた「特定条件」を満たさないよう、アプリを改善するしかありません。
Androidのソースコードを確認してみたのですが、他の方法での回避は難しそうでした。
また、「特定条件を満たすとLetterboxingになる端末なのか?」を正確に判別する方法は現時点(2024/10/02)で存在しないようです。
なので、「Android 12以上であればLetterboxingになる可能性あり」と考えておくしかありません。
アプリの特性上、特定の画面ではActivityの向きを固定したいのですが?
わかります。
私が開発に携わっているアプリでも、同様な悩みを抱えています。
一例として、YouTubeアプリの挙動が参考になります。
YouTubeアプリのプレイヤー画面には「最大化」ボタンがあるのですが、このボタンの挙動は画面サイズにより異なります。
(下記の挙動は「開発者オプション」で「最小幅」を変更し、実際のアプリの振る舞いとadbから得た情報から推測したものです)
- 画面の短辺が600dp未満
- 縦画面で「最大化」ボタンを押した場合、Actiivtyを横画面指定にて最大化表示をおこなう
- 画面の短辺が600dp以上
- 縦画面で「最大化」ボタンを押した場合、Actiivtyは縦画面のまま(アプリから回転方向指示しない)最大化表示をおこなう
つまり、「画面の短辺が600dp未満かどうか」で挙動を変えているようです。
恐らく、「Letterboxingになる端末なのかどうか?」を直接的に知る方法が無いので、上記の条件で間接的に判定しているのでしょう。
「画面の短辺が600dp未満かどうか」の判定を実現する例を示します。
具体的には下記のcanBeSpecifiedOrientation()
がtrueを返したときのみ、Activityへの画面回転方向指示をおこないます。
fun Activity.canBeSpecifiedOrientation(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode) {
return false
}
// Letterboxing feature was introduced in Android 12 (API level 31),
// so orientation can always be specified below that.
if (VERSION.SDK_INT < VERSION_CODES.S) {
return true
}
val windowMetrics =
WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
val shortSidePixels = minOf(
windowMetrics.bounds.width(),
windowMetrics.bounds.height(),
)
val shortSideDp = shortSidePixels / resources.displayMetrics.density
return shortSideDp < 600
}
上記のコードでは考慮していますが、マルチウインドウモードでの画面回転方向指示は必ず避けましょう。マルチウインドウモードであろうと、「特定のデバイス」上でアプリが画面回転方向を指示すると、Letterboxing表示になるからです。
今後について
Google的には「端末の画面向きはOSから指定するべきで、アプリで指定するのは止めて欲しい」という事なのでしょう。
そして、Android 15でedge-to-edgeが強制されたように、いずれは「アプリでの画面回転方向指示が無視される」という挙動が強制される可能性があります。
実際、実験的な機能ではありますがPixel 9 Pro Foldではアプリごとにアスペクト比を強制的に変更できます。
例えばFull screen指定すると、アプリ側のアスペクト比指定と縦画面指定固定を無視して縦画面でも横画面でもフルスクリーン表示できます。
つまり、縦画面固定のアプリでもユーザーから「横画面で表示が崩れる」という指摘を頂く可能性がある、という事です。
また、Desktop windowingという、アプリのウインドウサイズを自由に変更できる機能のDeveloper previewも始まっています。
今のうちからできる範囲で少しずつ、アプリで画面回転方向指示するのを止め、色々な画面サイズに対応していった方が良いでしょう。
Discussion