動作の変更点: Android 15 以上をターゲットとするアプリ

これまでのリリースと同様、Android 15 には、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、Android 15 以上をターゲットとするアプリにのみ適用されます。アプリが Android 15 以上をターゲットとする場合は、必要に応じてアプリを変更し、下記の動作に適切に対応できるようにしてください。

アプリの targetSdkVersion に関係なく、Android 15 で実行されるすべてのアプリに影響する動作変更のリストも必ずご確認ください。

コア機能

Android 15 では、Android システムのさまざまなコア機能が変更または拡張されています。

フォアグラウンド サービスの変更

Android 15 では、フォアグラウンド サービスに次の変更を加えます。

データ同期フォアグラウンド サービスのタイムアウト動作

Android 15 では、Android 15(API レベル 35)以降をターゲットとするアプリに対して、dataSync に新しいタイムアウト動作が導入されます。この動作は、新しい mediaProcessing フォアグラウンド サービス タイプにも適用されます。

システムは、アプリの dataSync サービスを 24 時間以内に合計 6 時間実行することを許可します。その後、システムは実行中のサービスの Service.onTimeout(int, int) メソッド(Android 15 で導入)を呼び出します。この時点で、サービスは Service.stopSelf() を呼び出すために数秒間待機します。Service.onTimeout() が呼び出されると、サービスはフォアグラウンド サービスと見なされなくなります。サービスが Service.stopSelf() を呼び出さない場合、システムは内部例外をスローします。例外は Logcat に次のメッセージとともに記録されます。

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"

この動作の変更による問題を回避するには、次のいずれかを行います。

  1. サービスに新しい Service.onTimeout(int, int) メソッドを実装します。アプリがコールバックを受信したら、数秒以内に stopSelf() を呼び出します。(アプリをすぐに停止しないと、システムは障害を生成します)。
  2. アプリの dataSync サービスが、24 時間で合計 6 時間を超えて実行されていないことを確認します(ユーザーがアプリを操作してタイマーをリセットする場合を除きます)。
  3. dataSync フォアグラウンド サービスは、直接のユーザー操作の結果としてのみ起動します。サービスの開始時にアプリはフォアグラウンドにあるため、サービスはバックグラウンドに移行してから 6 時間すべてかかります。
  4. dataSync フォアグラウンド サービスを使用する代わりに、代替の API を使用してください。

アプリの dataSync フォアグラウンド サービスが過去 24 時間以内に 6 時間実行されている場合、ユーザーがアプリをフォアグラウンドに表示した(これによりタイマーがリセットされる)場合を除き、別の dataSync フォアグラウンド サービスを開始することはできません。別の dataSync フォアグラウンド サービスを開始しようとすると、システムは ForegroundServiceStartNotAllowedException をスローし、「フォアグラウンド サービス タイプ dataSync の制限時間はすでに経過しています」などのエラー メッセージを出力します。

テスト

アプリの動作をテストするには、アプリが Android 15 をターゲットとしていない場合でも、データ同期のタイムアウトを有効にできます(アプリが Android 15 デバイスで実行されている場合)。タイムアウトを有効にするには、次の adb コマンドを実行します。

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

タイムアウト期間を調整して、上限に達したときアプリの動作を簡単にテストすることもできます。新しいタイムアウト期間を設定するには、次の adb コマンドを実行します。

adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds

新しいメディア処理フォアグラウンド サービス タイプ

Android 15 では、新しいフォアグラウンド サービス タイプ mediaProcessing が導入されています。このサービスタイプは、メディア ファイルのコード変換などのオペレーションに適しています。たとえば、メディアアプリが音声ファイルをダウンロードし、再生する前に別の形式に変換する必要がある場合があります。mediaProcessing フォアグラウンド サービスを使用すると、アプリがバックグラウンドにあっても変換を続行できます。

システムは、アプリの mediaProcessing サービスを 24 時間以内に合計 6 時間実行することを許可します。その後、システムは実行中のサービスの Service.onTimeout(int, int) メソッド(Android 15 で導入)を呼び出します。この時点で、サービスは Service.stopSelf() を呼び出すために数秒間待機します。サービスが Service.stopSelf() を呼び出さない場合、システムは内部例外をスローします。例外は Logcat に次のメッセージとともに記録されます。

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"

この例外を回避するには、次のいずれかを行います。

  1. サービスに新しい Service.onTimeout(int, int) メソッドを実装します。アプリがコールバックを受信したら、数秒以内に stopSelf() を呼び出します。(アプリをすぐに停止しないと、システムは障害を生成します)。
  2. アプリの mediaProcessing サービスが 24 時間以内に合計 6 時間を超えて実行されないようにします(ユーザーがアプリを操作してタイマーをリセットする場合を除く)。
  3. mediaProcessing フォアグラウンド サービスは、ユーザーが直接操作した結果としてのみ開始します。サービスが開始されたときにアプリはフォアグラウンドにあるため、アプリがバックグラウンドに移動した後も 6 時間間サービスは実行されます。
  4. mediaProcessing フォアグラウンド サービスを使用する代わりに、WorkManager などの代替 API を使用してください。

アプリの mediaProcessing フォアグラウンド サービスが過去 24 時間以内に 6 時間実行されている場合、ユーザーがアプリをフォアグラウンドに表示して(タイマーがリセットされる)場合を除き、別の mediaProcessing フォアグラウンド サービスを開始することはできません。別の mediaProcessing フォアグラウンド サービスを開始しようとすると、システムによって ForegroundServiceStartNotAllowedException がスローされ、「フォアグラウンド サービス タイプ mediaProcessing で時間制限がすでになくなりました」などのエラー メッセージが表示されます。

mediaProcessing サービスタイプについて詳しくは、Android 15 のフォアグラウンド サービス タイプの変更: メディア処理をご覧ください。

テスト

アプリの動作をテストするには、アプリが Android 15 をターゲットとしていない場合でも、メディア処理のタイムアウトを有効にできます(アプリが Android 15 デバイスで実行されている場合)。タイムアウトを有効にするには、次の adb コマンドを実行します。

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

タイムアウト期間を調整して、上限に達したときアプリの動作を簡単にテストすることもできます。新しいタイムアウト期間を設定するには、次の adb コマンドを実行します。

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds

フォアグラウンド サービスを起動する BOOT_COMPLETED ブロードキャスト レシーバの制限

在启动 BOOT_COMPLETED 广播接收器方面存在新限制 前台服务。BOOT_COMPLETED 接收器能启动 以下类型的前台服务:

如果 BOOT_COMPLETED 接收器尝试启动任何上述类型的前台 服务,系统会抛出 ForegroundServiceStartNotAllowedException

测试

如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。运行以下 adb 命令:

adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name

如需在不重启设备的情况下发送 BOOT_COMPLETED 广播,请运行以下 adb 命令:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name

アプリが SYSTEM_ALERT_WINDOW 権限を保持しているときにフォアグラウンド サービスを開始する場合の制限

以前は、アプリが SYSTEM_ALERT_WINDOW 権限を保持している場合、アプリが現在バックグラウンドで実行されている場合でも、フォアグラウンド サービスを起動できました(バックグラウンドでの起動制限の免除で説明しています)。

アプリが Android 15 をターゲットとしている場合、この免除はより限定的になりました。アプリには SYSTEM_ALERT_WINDOW 権限が必要になり、また、表示可能なオーバーレイ ウィンドウも必要になります。つまり、フォアグラウンド サービスを開始する前に、アプリがまず TYPE_APPLICATION_OVERLAY ウィンドウを起動、そのウィンドウを表示する必要があります。

アプリがこれらの新しい要件を満たさずにバックグラウンドからフォアグラウンド サービスを起動しようとすると(他の例外がない限り)、システムは ForegroundServiceStartNotAllowedException をスローします。

アプリが SYSTEM_ALERT_WINDOW 権限を宣言し、バックグラウンドからフォアグラウンド サービスを起動する場合、この変更の影響を受ける可能性があります。アプリが ForegroundServiceStartNotAllowedException を取得した場合は、アプリの処理順序を確認し、バックグラウンドからフォアグラウンド サービスを開始する前に、アプリにアクティブなオーバーレイ ウィンドウがすでに存在することを確認します。オーバーレイ ウィンドウが現在表示されているかどうかを確認するには、View.getWindowVisibility() を呼び出します。また、View.onWindowVisibilityChanged() を上書きして、可視性が変更されるたびに通知を受け取ることもできます。

テスト

アプリの動作をテストするには、アプリが Android 15 をターゲットとしていない場合でも、これらの新しい制限を有効にできます(アプリが Android 15 デバイスで実行されている場合)。バックグラウンドからフォアグラウンド サービスを起動する際の新しい制限を有効にするには、次の adb コマンドを実行します。

adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name

アプリがサイレント モードのグローバル状態を変更できるタイミングの変更

Android 15(API レベル 35)以降をターゲットとするアプリは、デバイスのサイレント(DND)モードのグローバル状態やポリシーを変更できなくなりました(ユーザー設定の変更や DND モードのオフによる変更も含みます)。代わりに、アプリは AutomaticZenRule を提供する必要がある。システムは、既存の最も制限の厳しいポリシーが優先されるスキームで、これをグローバル ポリシーに統合します。以前はグローバル状態に影響していた既存の API(setInterruptionFiltersetNotificationPolicy)を呼び出すと、暗黙的な AutomaticZenRule が作成または更新されます。この AutomaticZenRule は、API 呼び出しの呼び出しサイクルに応じてオンまたはオフに切り替わります。

この変更は、アプリが setInterruptionFilter(INTERRUPTION_FILTER_ALL) を呼び出し、その呼び出しによって所有者によって以前に有効にされた AutomaticZenRule が無効になることを想定している場合にのみ、検出可能な動作に影響します。

OpenJDK API の変更

Android 15 将继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致。

以下变更可能会影响以 Android 15(API 级别 35)为目标平台的应用的兼容性:

  • 对字符串格式化 API 进行了更改:现在,使用以下 String.format()Formatter.format() API 时,对实参索引、标志、宽度和精度的验证要求变得更加严格:

    例如,当使用参数索引 0(格式字符串中的 %0)时,系统会抛出以下异常:

    IllegalFormatArgumentIndexException: Illegal format argument index = 0
    

    在这种情况下,可以使用实参索引 1(格式字符串中的 %1)来解决此问题。

  • Arrays.asList(...).toArray() 的组件类型所做的更改:使用 Arrays.asList(...).toArray() 时,所得数组的组件类型现在是 Object,而不是底层数组元素的类型。因此,以下代码会抛出 ClassCastException

    String[] elements = (String[]) Arrays.asList("one", "two").toArray();
    

    在这种情况下,为了在生成的数组中保留 String 作为组件类型,您可以改用 Collection.toArray(Object[])

    String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
    
  • 语言代码处理方面的变更:使用 Locale API 时,希伯来语、意第绪语和印度尼西亚语的语言代码不再转换为其过时的形式(希伯来语:iw、意第绪语:ji 和印度尼西亚语:in)。指定这些语言区域的语言代码时,请改用 ISO 639-1 中的代码(希伯来语:he、意第绪语:yi 和印度尼西亚语:id)。

  • 随机整数序列的更改:根据 https://bugs.openjdk.org/browse/JDK-8301574 中所做的更改,以下 Random.ints() 方法现在返回的数字序列与 Random.nextInt() 方法返回的数字序列不同:

    一般来说,此更改不应导致应用出现破坏性行为,但您的代码不应期望从 Random.ints() 方法生成的序列与 Random.nextInt() 相匹配。

在您更新应用 build 配置中的 compileSdk 以使用 Android 15(API 级别 35)后,新的 SequencedCollection API 可能会影响应用的兼容性:

  • kotlin-stdlibMutableList.removeFirst()MutableList.removeLast() 扩展函数的冲突

    Java 中的 List 类型会映射到 Kotlin 中的 MutableList 类型。 由于 List.removeFirst()List.removeLast() API 已在 Android 15(API 级别 35)中引入,因此 Kotlin 编译器会将函数调用(例如 list.removeFirst())静态解析为新的 List API,而不是 kotlin-stdlib 中的扩展函数。

    如果某个应用重新编译时将 compileSdk 设置为 35,并将 minSdk 设置为 34 或更低值,然后该应用在 Android 14 及更低版本上运行,则会抛出运行时错误:

    java.lang.NoSuchMethodError: No virtual method
    removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
    

    Android Gradle 插件中现有的 NewApi lint 选项可以捕获这些新的 API 用法。

    ./gradlew lint
    
    MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi]
          list.removeFirst()
    

    如需修正运行时异常和 lint 错误,可以在 Kotlin 中将 removeFirst()removeLast() 函数调用分别替换为 removeAt(0)removeAt(list.lastIndex)。如果您使用的是 Android Studio Ladybug | 2024.1.3 或更高版本,它还会针对这些错误提供快速修复选项。

    如果已停用 lint 选项,请考虑移除 @SuppressLint("NewApi")lintOptions { disable 'NewApi' }

  • 与 Java 中的其他方法发生冲突

    现有类型中添加了新方法,例如 ListDeque。这些新方法可能与具有相同名称和实参类型的其他接口和类中的方法不兼容。如果方法签名发生不兼容的冲突,javac 编译器会输出 build 时错误。例如:

    错误示例 1:

    javac MyList.java
    
    MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List
      public void removeLast() {
                  ^
      return type void is not compatible with Object
      where E is a type-variable:
        E extends Object declared in interface List
    

    错误示例 2:

    javac MyList.java
    
    MyList.java:7: error: types Deque<Object> and List<Object> are incompatible;
    public class MyList implements  List<Object>, Deque<Object> {
      both define reversed(), but with unrelated return types
    1 error
    

    错误示例 3:

    javac MyList.java
    
    MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible;
    public static class MyList implements List<Object>, MyInterface<Object> {
      class MyList inherits unrelated defaults for getFirst() from types List and MyInterface
      where E#1,E#2 are type-variables:
        E#1 extends Object declared in interface List
        E#2 extends Object declared in interface MyInterface
    1 error
    

    如需修复这些 build 错误,实现这些接口的类应使用兼容的返回类型替换相应方法。例如:

    @Override
    public Object getFirst() {
        return List.super.getFirst();
    }
    

セキュリティ

Android 15 には、悪意のあるアプリからアプリとユーザーを保護するために、システムのセキュリティを強化する変更が含まれています。

制限付き TLS バージョン

Android 15 では、TLS バージョン 1.0 および 1.1 の使用が制限されています。これまではこれらのバージョンは Android で非推奨でしたが、現在は Android 15 をターゲットとするアプリで許可されないようになりました。

バックグラウンド アクティビティの安全な起動

Android 15 では、悪意のあるバックグラウンド アプリが他のアプリをフォアグラウンドに移動させたり、権限を昇格させたり、ユーザー インタラクションを悪用したりすることを防ぐ変更が加えられ、悪意のあるアプリからユーザーを保護し、デバイスの制御性を高めています。Android 10(API レベル 29)以降、バックグラウンド アクティビティの起動が制限されています。

その他の変更点

  • PendingIntent クリエイターのデフォルトをバックグラウンド アクティビティの起動をブロックに変更。これにより、アプリが誤って PendingIntent を作成し、悪意のある行為者によって不正使用されるのを防ぐことができます。
  • PendingIntent 送信者が許可しない限り、アプリをフォアグラウンドに移動しないでください。この変更は、悪意のあるアプリがバックグラウンドでアクティビティを開始する機能を悪用することを防ぐことを目的としています。デフォルトでは、作成者がバックグラウンド アクティビティの起動権限を許可するか、送信者がバックグラウンド アクティビティの起動権限を持っている場合を除き、アプリがタスクスタックをフォアグラウンドに移動することは許可されません。
  • タスクスタックの最上位のアクティビティがタスクを完了する方法を制御します。最上位のアクティビティがタスクを終了すると、Android は最後にアクティブだったタスクに戻ります。また、最上位でないアクティビティがタスクを終了した場合、Android はホーム画面に戻ります。この最上位でないアクティビティの終了はブロックされません。
  • 他のアプリから任意の Activity が自分のタスクに起動されるのを防ぎます。この変更により、悪意のあるアプリが他のアプリからのものに見せかけたアクティビティを作成してユーザーをフィッシングするのを防ぐことができます。
  • 非表示のウィンドウがバックグラウンド アクティビティの起動の対象にならないようにブロック。これにより、悪意のあるアプリがバックグラウンド アクティビティの起動を不正使用して、ユーザーに不要なコンテンツや悪意のあるコンテンツを表示するのを防ぐことができます。

より安全なインテント

Android 15 では、インテント用に StrictMode が導入されています。

Intent の使用違反に関する詳細なログを表示するには、次の方法を使用します。

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        .detectUnsafeIntentLaunch()
        .build()
    )
}

Java

public void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
            .detectUnsafeIntentLaunch()
            .build());
}

ユーザー エクスペリエンスとシステム UI

Android 15 には、より一貫性のある直感的なユーザー エクスペリエンスを実現するための変更が含まれています。

ウィンドウ インセットの変更

Android 15 では、ウィンドウの切り欠きに関連する 2 つの変更があります。エッジツーエッジがデフォルトで適用され、システムバーのデフォルト構成などの構成も変更されています。

エッジ ツー エッジの適用

アプリが Android 15(API レベル 35)をターゲットとしている場合、Android 15 を搭載しているデバイスではデフォルトでエッジツーエッジ表示となります。

Android 14 をターゲットとし、Android 15 デバイスでエッジ ツー エッジではないアプリ。


Android 15(API レベル 35)をターゲットとし、Android 15 デバイスでエッジ ツー エッジのアプリ。このアプリでは、インセットを自動的に適用するマテリアル デザイン 3 の Compose コンポーネントを主に使っています。この画面は、Android 15 でのエッジ ツー エッジの適用から悪影響を受けません。

これは、アプリの UI に悪影響を及ぼす可能性のある互換性を破る変更です。この変更は、次の UI 領域に影響します。

  • ジェスチャー ハンドル ナビゲーション バー
    • デフォルトでは透明です。
    • 下部のオフセットが無効になっているため、インセットが適用されない限り、コンテンツはシステム ナビゲーション バーの背後に描画されます。
    • setNavigationBarColorR.attr#navigationBarColor は非推奨であり、ジェスチャー ナビゲーションには影響しません。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced は、引き続きジェスチャー ナビゲーションに影響しません。
  • 3 ボタン ナビゲーション
    • デフォルトでは不透明度は 80% に設定され、ウィンドウの背景色と一致する可能性があります。
    • 下部のオフセットが無効になり、インセットが適用されない限り、コンテンツがシステム ナビゲーション バーの背後に描画されるようになりました。
    • setNavigationBarColorR.attr#navigationBarColor は、デフォルトでウィンドウの背景に一致するように設定されています。このデフォルトを適用するには、ウィンドウの背景がカラー ドローアブルである必要があります。この API は非推奨ですが、3 ボタン ナビゲーションに引き続き影響します。
    • setNavigationBarContrastEnforcedR.attr#navigationBarContrastEnforced はデフォルトで true になっており、3 ボタン ナビゲーション全体に 80% の不透明度の背景が追加されます。
  • ステータスバー
    • デフォルトでは透明です。
    • 上部のオフセットが無効になっているため、インセットが適用されない限り、コンテンツはステータスバーの背後に描画されます。
    • setStatusBarColorR.attr#statusBarColor は非推奨であり、Android 15 では無効になっています。
    • setStatusBarContrastEnforcedR.attr#statusBarContrastEnforced は非推奨ですが、Android 15 でも引き続き有効です。
  • ディスプレイ カットアウト
    • フローティング ウィンドウ以外の layoutInDisplayCutoutModeLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS にする必要があります。SHORT_EDGESNEVERDEFAULTALWAYS として解釈され、ディスプレイ カットアウトによる黒いバーがユーザーに表示されず、端から端まで表示されます。

次の例は、Android 15(API レベル 35)をターゲットにする前後のアプリと、インセットを適用する前後のアプリを示しています。この例は包括的なものではなく、Android Auto では異なる表示になる可能性があります。

Android 14 をターゲットとし、Android 15 デバイスでエッジ ツー エッジではないアプリ。
Android 15(API レベル 35)をターゲットとし、Android 15 デバイスでエッジ ツー エッジのアプリ。ただし、Android 15 のエッジ ツー エッジの強制適用により、多くの要素がステータスバー、3 ボタン ナビゲーション バー、ディスプレイ カットアウトによって隠れてしまいます。非表示の UI には、Material 2 の上部アプリバー、フローティング アクション ボタン、リスト項目が含まれます。
Android 15(API レベル 35)をターゲットとするアプリは、Android 15 デバイスでエッジ ツー エッジになり、UI が隠れないようにインセットを適用します。
アプリがすでにエッジ ツー エッジに対応している場合に確認すること

アプリがすでに エッジ ツー エッジでインセットを適用している場合、次のシナリオを除き、ほとんど影響はありません。ただし、影響を受けないと思われる場合でも、アプリをテストすることをおすすめします。

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS の代わりに SHORT_EDGESNEVERDEFAULT を使用する Activity などの非フローティング ウィンドウがあります。アプリが起動時にクラッシュする場合は、スプラッシュ画面が原因である可能性があります。コア スプラッシュ画面の依存関係を 1.2.0-alpha01 以降にアップグレードするか、window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always を設定します。
  • トラフィックが少なく、UI が隠れている画面がある可能性があります。これらのアクセス頻度の低い画面に、隠れた UI がないことを確認します。トラフィックの少ない画面には、次のものがあります。
    • オンボーディング画面またはログイン画面
    • 設定ページ
アプリがエッジ ツー エッジに対応していない場合に確認すること

アプリがエッジ ツー エッジに対応していない場合は、影響を受ける可能性が高いです。すでにエッジ ツー エッジに対応しているアプリのシナリオに加えて、次の点も考慮する必要があります。

  • アプリが Compose でマテリアル デザイン 3 のコンポーネント(androidx.compose.material3)(TopAppBarBottomAppBarNavigationBar など)を使用している場合、これらのコンポーネントはインセットを自動的に処理するため、影響を受けない可能性があります。
  • アプリが Compose でマテリアル デザイン 2 のコンポーネント(androidx.compose.material)を使用している場合、コンポーネントはインセットを自動的には処理しません。ただし、インセットにアクセスして手動で適用することはできます。androidx.compose.material 1.6.0 以降では、windowInsets パラメータを使用して、BottomAppBarTopAppBarBottomNavigationNavigationRail にインセットを手動で適用します。同様に、Scaffold には contentWindowInsets パラメータを使用します。
  • アプリでビューとマテリアル コンポーネント(com.google.android.material)を使用する場合、ビューベースのマテリアル コンポーネントの多く(BottomNavigationViewBottomAppBarNavigationRailViewNavigationView など)はインセットを処理します。追加の作業は不要です。ただし、AppBarLayout を使用する場合は android:fitsSystemWindows="true" を追加する必要があります。
  • カスタム コンポーザブルの場合は、インセットをパディングとして手動で適用します。コンテンツが Scaffold 内にある場合は、Scaffold パディング値を使用してインセットを使用できます。それ以外の場合は、WindowInsets のいずれかを使用してパディングを適用します。
  • アプリがビューと BottomSheetSideSheet、またはカスタム コンテナを使用する場合、ViewCompat.setOnApplyWindowInsetsListener を使用してパディングを適用します。RecyclerView については、このリスナーを使用してパディングを適用して、さらに clipToPadding="false" を追加します。
アプリでカスタム バックグラウンド保護を提供する必要があるかどうかを確認する

アプリで 3 ボタン ナビゲーションまたはステータスバーにカスタムの背景保護を提供する必要がある場合は、WindowInsets.Type#tappableElement() を使用して 3 ボタン ナビゲーション バーの高さを取得するか、WindowInsets.Type#statusBars を使用して、システムバーの背後にコンポーザブルまたはビューを配置する必要があります。

エッジ ツー エッジに関するその他のリソース

インセットの適用に関するその他の考慮事項については、エッジ ツー エッジ ビューエッジ ツー エッジ Compose のガイドをご覧ください。

サポート終了 API

次の API は非推奨ですが、無効にはなっていません。

次の API は非推奨となり、無効になっています。

安定版の構成

アプリが Android 15(API レベル 35)以上をターゲットにしている場合、Configuration はシステムバーを除外しません。レイアウトの計算に Configuration クラスの画面サイズを使用している場合は、必要に応じて適切な ViewGroupWindowInsetsWindowMetricsCalculator などのより良い代替手段に置き換える必要があります。

Configuration は API 1 以降で利用可能です。通常は Activity.onConfigurationChanged から取得します。ウィンドウの密度、向き、サイズなどの情報が提供されます。Configuration から返されるウィンドウ サイズの重要な特徴の 1 つは、以前はシステムバーが除外されていたことです。

構成サイズは通常、/res/layout-h500dp などのリソース選択に使用されますが、これは依然として有効なユースケースです。ただし、レイアウトの計算に使用することは常に推奨されていません。その場合は、今すぐ離れてください。ユースケースに応じて、Configuration の使用をより適切なものに置き換える必要があります。

レイアウトの計算に使用する場合は、CoordinatorLayoutConstraintLayout などの適切な ViewGroup を使用します。システム ナビバーの高さを判断するために使用する場合は、WindowInsets を使用します。アプリ ウィンドウの現在のサイズを知りたい場合は、computeCurrentWindowMetrics を使用します。

この変更の影響を受けるフィールドは次のとおりです。

  • Configuration.screenWidthDp サイズと screenHeightDp サイズでシステムバーが除外されなくなりました。
  • Configuration.smallestScreenWidthDp は、screenWidthDpscreenHeightDp の変更の影響を間接的に受けます。
  • Configuration.orientation は、正方形に近いデバイスの screenWidthDpscreenHeightDp の変更によって間接的に影響を受けます。
  • Display.getSize(Point) は、Configuration の変更の影響を間接的に受けます。これは API レベル 30 以降で非推奨になりました。
  • Display.getMetrics() は、API レベル 33 以降、すでにこの動作をしています。

elegantTextHeight 属性のデフォルト値が true になりました

Android 15(API レベル 35)をターゲットとするアプリの場合、elegantTextHeight TextView 属性はデフォルトで true になります。これにより、デフォルトで使用されるコンパクトなフォントが、読みやすく大きな縦方向の測定値を持つスクリプトに置き換えられます。コンパクト フォントは、レイアウトの分割を防ぐために導入されました。Android 13(API レベル 33)では、fallbackLineSpacing 属性を使用してテキスト レイアウトの垂直方向の高さを伸ばすことで、このような分割の多くを防ぐことができます。

Android 15 では、コンパクト フォントは引き続きシステムに残るため、アプリで elegantTextHeightfalse に設定して以前と同じ動作を実現できますが、今後のリリースでサポートされる可能性は低いです。そのため、アプリがアラビア語、ラオス語、ミャンマー語、タミル語、グジャラート語、カンナダ語、マラヤーラム語、オディア語、テルグ語、タイ語のスクリプトをサポートしている場合は、elegantTextHeighttrue に設定してアプリをテストします。

Android 14(API レベル 34)以前をターゲットとするアプリの
elegantTextHeight の動作
Android 15 をターゲットとするアプリの elegantTextHeight の動作。

複雑な文字の形状に合わせて TextView の幅が変更される

Android の以前のバージョンでは、複雑なシェーピングを持つ一部の筆記体フォントや言語では、文字が前の文字または次の文字の領域に描画されることがあります。場合によっては、このような文字の開始位置や終了位置が切り詰められていました。Android 15 以降では、TextView はこのような文字に十分なスペースを描画するための幅を割り当て、アプリがクリッピングを防ぐために左側に追加の余白をリクエストできるようにします。

この変更は TextView が幅を決定する方法に影響するため、アプリが Android 15(API レベル 35)以降をターゲットとしている場合、TextView はデフォルトでより多くの幅を割り当てます。この動作を有効または無効にするには、TextViewsetUseBoundsForWidth API を呼び出します。

左側の余白を追加すると、既存のレイアウトの位置がずれる可能性があるため、Android 15 以降をターゲットとするアプリでも、デフォルトでは余白は追加されません。ただし、setShiftDrawingOffsetForStartOverhang を呼び出すことで、クリッピングを防ぐためにパディングを追加できます。

次の例は、これらの変更によって、一部のフォントと言語のテキスト レイアウトがどのように改善されるかを示しています。

英語のテキストを筆記体フォントで表示する場合の標準レイアウト。一部の文字が切り取られている。対応する XML は次のとおりです。

<TextView
    android:fontFamily="cursive"
    android:text="java" />
同じ英語のテキストのレイアウト。幅とパディングが追加されています。対応する XML は次のとおりです。

<TextView
    android:fontFamily="cursive"
    android:text="java"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />
タイ語テキストの標準レイアウト。一部の文字が切り取られている。 対応する XML は次のとおりです。

<TextView
    android:text="คอมพิวเตอร์" />
幅とパディングを追加した、同じタイ語のテキストのレイアウト。対応する XML は次のとおりです。

<TextView
    android:text="คอมพิวเตอร์"
    android:useBoundsForWidth="true"
    android:shiftDrawingOffsetForStartOverhang="true" />

EditText のロケール対応のデフォルトの行の高さ

以前のバージョンの Android では、テキスト レイアウトは、現在の言語 / 地域に一致するフォントの行の高さに合うようにテキストの高さを伸ばしていました。たとえば、コンテンツが日本語の場合、日本語フォントの行間がラテン文字フォントよりも少し大きいため、テキストの高さが少し大きくなっていました。ただし、次の画像に示すように、このような行の高さの違いにもかかわらず、EditText 要素は、使用されている言語 / 地域に関係なく、均一にサイズ設定されていました。

英語(en)、日本語(ja)、ビルマ語(my)のテキストを含めることができる EditText 要素を表す 3 つのボックス。これらの言語の行の高さは異なりますが、EditText の高さは同じです。

Android 15(API レベル 35)をターゲットとするアプリの場合、指定されたロケールの参照フォントに合わせて、EditText の最小行の高さが予約されるようになりました。これは次の図に示すとおりです。

英語(en)、日本語(ja)、ビルマ語(my)のテキストを含めることができる EditText 要素を表す 3 つのボックス。EditText の高さに、これらの言語のフォントのデフォルトの行の高さに対応するスペースが追加されました。

必要に応じて、useLocalePreferredLineHeightForMinimum 属性を false に指定することで、以前の動作を復元できます。また、Kotlin と Java で setMinimumFontMetrics API を使用して、カスタムの最小垂直指標を設定することもできます。

カメラとメディア

Android 15 では、Android 15 以上をターゲットとするアプリのカメラとメディアの動作が次のように変更されています。

音声フォーカス リクエストの制限

Android 15(API レベル 35)をターゲットとするアプリが音声フォーカスをリクエストするには、最上位のアプリであるか、フォアグラウンド サービスを実行している必要があります。アプリがこれらの要件のいずれかを満たしていないときにフォーカスをリクエストしようとすると、呼び出しは AUDIOFOCUS_REQUEST_FAILED を返します。

音声フォーカスの詳細については、音声フォーカスを管理するをご覧ください。

非 SDK の制限の更新

Android 15 では、Android デベロッパーの協力と直近の内部テストに基づいて、制限を受ける非 SDK インターフェースのリストが更新されています。Google は、非 SDK インターフェースを制限する前に、可能な限り、その代わりとなる公開インターフェースを利用可能にしています。

Android 15 をターゲットとしないアプリでは、この変更の一部はすぐには影響しない可能性があります。ただし、アプリのターゲット API レベルに応じて、アプリが一部の非 SDK インターフェースにアクセスできる場合もありますが、非 SDK のメソッドまたはフィールドを使用すると、アプリが機能しなくなるリスクが高くなります。

アプリが非 SDK インターフェースを使用しているかどうか不明な場合は、アプリをテストして確認できます。アプリが非 SDK インターフェースに依存している場合は、SDK の代替インターフェースへの移行を計画してください。ただし Google も、一部のアプリには非 SDK インターフェースを使用する正当なユースケースがあると承知しています。アプリの機能に使用している非 SDK インターフェースの代わりが見つからない場合は、新しい公開 API をリクエストしてください。

Android の今回のリリースの変更について詳しくは、非 SDK インターフェースの制限に関する Android 15 での変更点をご覧ください。非 SDK インターフェース全般について詳しくは、非 SDK インターフェースの制限をご覧ください。