これまでのリリースと同様、Android 15 には、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、Android 15 以上をターゲットとするアプリにのみ適用されます。アプリが Android 15 以上をターゲットとする場合は、必要に応じてアプリを変更し、下記の動作に適切に対応できるようにしてください。
アプリの targetSdkVersion に関係なく、Android 15 で実行されるすべてのアプリに影響する動作変更のリストも必ずご確認ください。
コア機能
Android 15 では、Android システムのさまざまなコア機能が変更または拡張されています。
フォアグラウンド サービスの変更
We are making the following changes to foreground services with Android 15.
- Data sync foreground service timeout behavior
- New media processing foreground service type
- Restrictions on
BOOT_COMPLETEDbroadcast receivers launching foreground services - Restrictions on starting foreground services while an app holds the
SYSTEM_ALERT_WINDOWpermission
Data sync foreground service timeout behavior
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]"
この動作の変更による問題を回避するには、次のいずれかを行います。
- サービスに新しい
Service.onTimeout(int, int)メソッドを実装します。アプリがコールバックを受信したら、数秒以内にstopSelf()を呼び出します。(アプリをすぐに停止しないと、システムは障害を生成します)。 - アプリの
dataSyncサービスが、24 時間で合計 6 時間を超えて実行されていないことを確認します(ユーザーがアプリを操作してタイマーをリセットする場合を除きます)。 dataSyncフォアグラウンド サービスは、直接のユーザー操作の結果としてのみ起動します。サービスの開始時にアプリはフォアグラウンドにあるため、サービスはバックグラウンドに移行してから 6 時間すべてかかります。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
New media processing foreground service type
Android 15 introduces a new foreground service type, mediaProcessing. This
service type is appropriate for operations like transcoding media files. For
example, a media app might download an audio file and need to convert it to a
different format before playing it. You can use a mediaProcessing foreground
service to make sure the conversion continues even while the app is in the
background.
The system permits an app's mediaProcessing services to run for a total of 6
hours in a 24-hour period, after which the system calls the running service's
Service.onTimeout(int, int) method (introduced in Android
15). At this time, the service has a few seconds to call
Service.stopSelf(). If the service does not
call Service.stopSelf(), the system throws an internal exception. The
exception is logged in Logcat with the following message:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
To avoid having the exception, you can do one of the following:
- Have your service implement the new
Service.onTimeout(int, int)method. When your app receives the callback, make sure to callstopSelf()within a few seconds. (If you don't stop the app right away, the system generates a failure.) - Make sure your app's
mediaProcessingservices don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer). - Only start
mediaProcessingforeground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background. - Instead of using a
mediaProcessingforeground service, use an alternative API, like WorkManager.
If your app's mediaProcessing foreground services have run for 6 hours in the
last 24, you cannot start another mediaProcessing foreground service unless
the user has brought your app to the foreground (which resets the timer). If you
try to start another mediaProcessing foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type mediaProcessing".
For more information about the mediaProcessing service type, see Changes to
foreground service types for Android 15: Media processing.
Testing
To test your app's behavior, you can enable media processing timeouts even if
your app is not targeting Android 15 (as long as the app is running on an
Android 15 device). To enable timeouts, run the following adb command:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
You can also adjust the timeout period, to make it easier to test how your
app behaves when the limit is reached. To set a new timeout period, run the
following adb command:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
Restrictions on BOOT_COMPLETED broadcast receivers launching foreground services
BOOT_COMPLETED ブロードキャスト レシーバに対する新しい制限事項がリリースされます
フォアグラウンド サービスの場合。BOOT_COMPLETED レシーバーは、API 呼び出しを起動できない
フォアグラウンド サービスのタイプを使用できます。
dataSynccameramediaPlaybackphoneCallmediaProjectionmicrophone(この制限は、次の日付よりmicrophoneに適用されています) Android 14)
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
Restrictions on starting foreground services while an app holds the SYSTEM_ALERT_WINDOW permission
Previously, if an app held the SYSTEM_ALERT_WINDOW permission, it could launch
a foreground service even if the app was currently in the background (as
discussed in exemptions from background start restrictions).
If an app targets Android 15, this exemption is now narrower. The app now needs
to have the SYSTEM_ALERT_WINDOW permission and also have a visible overlay
window. That is, the app needs to first launch a
TYPE_APPLICATION_OVERLAY window and the window
needs to be visible before you start a foreground service.
If your app attempts to start a foreground service from the background without
meeting these new requirements (and it does not have some other exemption), the
system throws ForegroundServiceStartNotAllowedException.
If your app declares the SYSTEM_ALERT_WINDOW permission
and launches foreground services from the background, it may be affected by this
change. If your app gets a ForegroundServiceStartNotAllowedException, check
your app's order of operations and make sure your app already has an active
overlay window before it attempts to start a foreground service from the
background. You can check if your overlay window is currently visible
by calling View.getWindowVisibility(), or you
can override View.onWindowVisibilityChanged()
to get notified whenever the visibility changes.
Testing
To test your app's behavior, you can enable these new restrictions even if your
app is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable these new restrictions on starting foreground services
from the background, run the following adb command:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
アプリがサイレント モードのグローバル状態を変更できるタイミングの変更
Android 15(API レベル 35)以降をターゲットとするアプリは、デバイスのサイレント(DND)モードのグローバル状態やポリシーを変更できなくなりました(ユーザー設定の変更や DND モードのオフによる変更も含みます)。代わりに、アプリは AutomaticZenRule を提供する必要がある。システムは、既存の最も制限の厳しいポリシーが優先されるスキームで、これをグローバル ポリシーに統合します。以前はグローバル状態に影響していた既存の API(setInterruptionFilter、setNotificationPolicy)を呼び出すと、暗黙的な AutomaticZenRule が作成または更新されます。この AutomaticZenRule は、API 呼び出しの呼び出しサイクルに応じてオンまたはオフに切り替わります。
この変更は、アプリが setInterruptionFilter(INTERRUPTION_FILTER_ALL) を呼び出し、その呼び出しによって所有者によって以前に有効にされた AutomaticZenRule が無効になることを想定している場合にのみ、検出可能な動作に影響します。
OpenJDK API の変更
Android 15 では、最新の OpenJDK LTS リリースの機能に合わせて Android のコアライブラリを更新する取り組みが引き続き行われています。
これらの変更の一部は、Android 15(API レベル 35)をターゲットとするアプリの互換性に影響する可能性があります。
String Formatting API を変更: 次の
String.format()API とFormatter.format()API を使用する場合、引数インデックス、フラグ、幅、精度の検証がより厳格になりました。String.format(String, Object[])String.format(Locale, String, Object[])Formatter.format(String, Object[])Formatter.format(Locale, String, Object[])
たとえば、引数インデックス 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]);言語コードの処理の変更:
LocaleAPI を使用する場合、ヘブライ語、イディッシュ語、インドネシア語の言語コードは、廃止された形式(ヘブライ語:iw、イディッシュ語:ji、インドネシア語:in)に変換されなくなりました。これらの言語のいずれかの言語コードを指定する場合は、代わりに ISO 639-1 のコード(ヘブライ語:he、イディッシュ語:yi、インドネシア語:id)を使用してください。ランダムな整数シーケンスの変更: https://bugs.openjdk.org/browse/JDK-8301574 で行われた変更に伴い、次の
Random.ints()メソッドはRandom.nextInt()メソッドとは異なる数値シーケンスを返すようになりました。一般に、この変更によってアプリの動作が損なわれることはありませんが、コードでは
Random.ints()メソッドから生成されたシーケンスがRandom.nextInt()と一致することを想定しないでください。
新しい SequencedCollection API は、アプリのビルド構成で compileSdk を更新して Android 15(API レベル 35)を使用すると、アプリの互換性に影響する可能性があります。
kotlin-stdlibのMutableList.removeFirst()拡張関数とMutableList.removeLast()拡張関数との競合Java の
List型は Kotlin のMutableList型にマッピングされます。List.removeFirst()API とList.removeLast()API は Android 15(API レベル 35)で導入されたため、Kotlin コンパイラは、関数呼び出し(list.removeFirst()など)をkotlin-stdlibの拡張関数ではなく、新しいListAPI に静的に解決します。compileSdkが35に設定され、minSdkが34以下に設定された状態でアプリが再コンパイルされ、Android 14 以下で実行されると、ランタイム エラーがスローされます。java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;Android Gradle プラグインの既存の
NewApilint オプションで、これらの新しい API の使用を検出できます。./gradlew lintMainActivity.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 の他のメソッドとの衝突
既存の型(
List、Dequeなど)に新しいメソッドが追加されました。これらの新しいメソッドは、他のインターフェースやクラスの同じ名前と引数の型のメソッドと互換性がない可能性があります。メソッド シグネチャの競合が互換性のない場合、javacコンパイラはビルド時のエラーを出力します。次に例を示します。エラーの例 1:
javac MyList.javaMyList.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.javaMyList.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.javaMyList.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これらのビルドエラーを修正するには、これらのインターフェースを実装するクラスで、互換性のある戻り値の型を使用してメソッドをオーバーライドする必要があります。次に例を示します。
@Override public Object getFirst() { return List.super.getFirst(); }
セキュリティ
Android 15 には、悪意のあるアプリからアプリとユーザーを保護するために、システムのセキュリティを強化する変更が含まれています。
制限付き TLS バージョン
Android 15 restricts the usage of TLS versions 1.0 and 1.1. These versions had previously been deprecated in Android, but are now disallowed for apps targeting Android 15.
バックグラウンド アクティビティの安全な起動
Android 15 では、悪意のあるバックグラウンド アプリが他のアプリをフォアグラウンドに移動させたり、権限を昇格させたり、ユーザー インタラクションを悪用したりすることを防ぐ変更が加えられ、悪意のあるアプリからユーザーを保護し、デバイスの制御性を高めています。Android 10(API レベル 29)以降、バックグラウンド アクティビティの起動が制限されています。
その他の変更点
PendingIntentクリエイターのデフォルトをバックグラウンド アクティビティの起動をブロックに変更。これにより、アプリが誤ってPendingIntentを作成し、悪意のある行為者によって不正使用されるのを防ぐことができます。PendingIntent送信者が許可しない限り、アプリをフォアグラウンドに移動しないでください。この変更は、悪意のあるアプリがバックグラウンドでアクティビティを開始する機能を悪用することを防ぐことを目的としています。デフォルトでは、作成者がバックグラウンド アクティビティの起動権限を許可するか、送信者がバックグラウンド アクティビティの起動権限を持っている場合を除き、アプリがタスクスタックをフォアグラウンドに移動することは許可されません。- タスクスタックの最上位のアクティビティがタスクを完了する方法を制御します。最上位のアクティビティがタスクを終了すると、Android は最後にアクティブだったタスクに戻ります。また、最上位でないアクティビティがタスクを終了した場合、Android はホーム画面に戻ります。この最上位でないアクティビティの終了はブロックされません。
- 他のアプリから任意の Activity が自分のタスクに起動されるのを防ぎます。この変更により、悪意のあるアプリが他のアプリからのものに見せかけたアクティビティを作成してユーザーをフィッシングするのを防ぐことができます。
- 非表示のウィンドウがバックグラウンド アクティビティの起動の対象にならないようにブロック。これにより、悪意のあるアプリがバックグラウンド アクティビティの起動を不正使用して、ユーザーに不要なコンテンツや悪意のあるコンテンツを表示するのを防ぐことができます。
より安全なインテント
Android 15 introduces StrictMode for
intents.
In order to see detailed logs about Intent usage violations, use following
method:
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 つの変更があります。エッジツーエッジがデフォルトで適用され、システムバーのデフォルト構成などの構成も変更されています。
Edge-to-edge enforcement
アプリが Android 15(API レベル 35)をターゲットとしている場合、Android 15 を搭載しているデバイスではデフォルトでエッジツーエッジ表示となります。
これは、アプリの UI に悪影響を及ぼす可能性のある互換性を破る変更です。この変更は、次の UI 領域に影響します。
- ジェスチャー ハンドル ナビゲーション バー
- デフォルトでは透明です。
- 下部のオフセットが無効になっているため、インセットが適用されない限り、コンテンツはシステム ナビゲーション バーの背後に描画されます。
setNavigationBarColorとR.attr#navigationBarColorは非推奨であり、ジェスチャー ナビゲーションには影響しません。setNavigationBarContrastEnforcedとR.attr#navigationBarContrastEnforcedは、引き続きジェスチャー ナビゲーションに影響しません。
- 3 ボタン ナビゲーション
- デフォルトでは不透明度は 80% に設定され、ウィンドウの背景色と一致する可能性があります。
- 下部のオフセットが無効になり、インセットが適用されない限り、コンテンツがシステム ナビゲーション バーの背後に描画されるようになりました。
setNavigationBarColorとR.attr#navigationBarColorは、デフォルトでウィンドウの背景に一致するように設定されています。このデフォルトを適用するには、ウィンドウの背景がカラー ドローアブルである必要があります。この API は非推奨ですが、3 ボタン ナビゲーションに引き続き影響します。setNavigationBarContrastEnforcedとR.attr#navigationBarContrastEnforcedはデフォルトで true になっており、3 ボタン ナビゲーション全体に 80% の不透明度の背景が追加されます。
- ステータスバー
- デフォルトでは透明です。
- 上部のオフセットが無効になっているため、インセットが適用されない限り、コンテンツはステータスバーの背後に描画されます。
setStatusBarColorとR.attr#statusBarColorは非推奨であり、Android 15 では無効になっています。setStatusBarContrastEnforcedとR.attr#statusBarContrastEnforcedは非推奨ですが、Android 15 でも引き続き有効です。
- ディスプレイ カットアウト
- フローティング ウィンドウ以外の
layoutInDisplayCutoutModeはLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSにする必要があります。SHORT_EDGES、NEVER、DEFAULTはALWAYSとして解釈され、ディスプレイ カットアウトによる黒いバーがユーザーに表示されず、端から端まで表示されます。
- フローティング ウィンドウ以外の
次の例は、Android 15(API レベル 35)をターゲットにする前後のアプリと、インセットを適用する前後のアプリを示しています。この例は包括的なものではなく、Android Auto では異なる表示になる可能性があります。
アプリがすでにエッジ ツー エッジに対応している場合に確認すること
アプリがすでに エッジ ツー エッジでインセットを適用している場合、次のシナリオを除き、ほとんど影響はありません。ただし、影響を受けないと思われる場合でも、アプリをテストすることをおすすめします。
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSの代わりにSHORT_EDGES、NEVER、DEFAULTを使用するActivityなどの非フローティング ウィンドウがあります。アプリが起動時にクラッシュする場合は、スプラッシュ画面が原因である可能性があります。コア スプラッシュ画面の依存関係を 1.2.0-alpha01 以降にアップグレードするか、window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.alwaysを設定します。- トラフィックが少なく、UI が隠れている画面がある可能性があります。これらのアクセス頻度の低い画面に、隠れた UI がないことを確認します。トラフィックの少ない画面には、次のものがあります。
- オンボーディング画面またはログイン画面
- 設定ページ
アプリがエッジ ツー エッジに対応していない場合に確認すること
アプリがエッジ ツー エッジに対応していない場合は、影響を受ける可能性が高いです。すでにエッジ ツー エッジに対応しているアプリのシナリオに加えて、次の点も考慮する必要があります。
- アプリが Compose でマテリアル デザイン 3 のコンポーネント(
androidx.compose.material3)(TopAppBar、BottomAppBar、NavigationBarなど)を使用している場合、これらのコンポーネントはインセットを自動的に処理するため、影響を受けない可能性があります。 - アプリが Compose でマテリアル デザイン 2 のコンポーネント(
androidx.compose.material)を使用している場合、コンポーネントはインセットを自動的には処理しません。ただし、インセットにアクセスして手動で適用することはできます。androidx.compose.material 1.6.0 以降では、windowInsetsパラメータを使用して、BottomAppBar、TopAppBar、BottomNavigation、NavigationRailにインセットを手動で適用します。同様に、ScaffoldにはcontentWindowInsetsパラメータを使用します。 - アプリでビューとマテリアル コンポーネント(
com.google.android.material)を使用する場合、ビューベースのマテリアル コンポーネントの多く(BottomNavigationView、BottomAppBar、NavigationRailView、NavigationViewなど)はインセットを処理します。追加の作業は不要です。ただし、AppBarLayoutを使用する場合はandroid:fitsSystemWindows="true"を追加する必要があります。 - カスタム コンポーザブルの場合は、インセットをパディングとして手動で適用します。コンテンツが
Scaffold内にある場合は、Scaffoldパディング値を使用してインセットを使用できます。それ以外の場合は、WindowInsetsのいずれかを使用してパディングを適用します。 - アプリがビューと
BottomSheet、SideSheet、またはカスタム コンテナを使用する場合、ViewCompat.setOnApplyWindowInsetsListenerを使用してパディングを適用します。RecyclerViewについては、このリスナーを使用してパディングを適用して、さらにclipToPadding="false"を追加します。
アプリでカスタム バックグラウンド保護を提供する必要があるかどうかを確認する
アプリで 3 ボタン ナビゲーションまたはステータスバーにカスタムの背景保護を提供する必要がある場合は、WindowInsets.Type#tappableElement() を使用して 3 ボタン ナビゲーション バーの高さを取得するか、WindowInsets.Type#statusBars を使用して、システムバーの背後にコンポーザブルまたはビューを配置する必要があります。
エッジ ツー エッジに関するその他のリソース
インセットの適用に関するその他の考慮事項については、エッジ ツー エッジ ビューとエッジ ツー エッジ Compose のガイドをご覧ください。
サポート終了 API
次の API は非推奨ですが、無効にはなっていません。
R.attr#enforceStatusBarContrastR.attr#navigationBarColor(3 ボタン ナビゲーション、アルファ値 80%)Window#isStatusBarContrastEnforcedWindow#setNavigationBarColor(3 ボタン ナビゲーション用、アルファ値 80%)Window#setStatusBarContrastEnforced
次の API は非推奨となり、無効になっています。
R.attr#navigationBarColor(ジェスチャー ナビゲーションの場合)R.attr#navigationBarDividerColorR.attr#statusBarColorWindow#setDecorFitsSystemWindowsWindow#getNavigationBarColorWindow#getNavigationBarDividerColorWindow#getStatusBarColorWindow#setNavigationBarColor(ジェスチャー ナビゲーションの場合)Window#setNavigationBarDividerColorWindow#setStatusBarColor
Stable configuration
If your app targets Android 15 (API level 35) or higher, Configuration no
longer excludes the system bars. If you use the screen size in the
Configuration class for layout calculation, you should replace it with better
alternatives like an appropriate ViewGroup, WindowInsets, or
WindowMetricsCalculator depending on your need.
Configuration has been available since API 1. It is typically obtained from
Activity.onConfigurationChanged. It provides information like window density,
orientation, and sizes. One important characteristic about the window sizes
returned from Configuration is that it previously excluded the system bars.
The configuration size is typically used for resource selection, such as
/res/layout-h500dp, and this is still a valid use case. However, using it for
layout calculation has always been discouraged. If you do so, you should move
away from it now. You should replace the use of Configuration with something
more suitable depending on your use case.
If you use it to calculate the layout, use an appropriate ViewGroup, such as
CoordinatorLayout or ConstraintLayout. If you use it to determine the height
of the system navbar, use WindowInsets. If you want to know the current size
of your app window, use computeCurrentWindowMetrics.
The following list describes the fields affected by this change:
Configuration.screenWidthDpandscreenHeightDpsizes no longer exclude the system bars.Configuration.smallestScreenWidthDpis indirectly affected by changes toscreenWidthDpandscreenHeightDp.Configuration.orientationis indirectly affected by changes toscreenWidthDpandscreenHeightDpon close-to-square devices.Display.getSize(Point)is indirectly affected by the changes inConfiguration. This was deprecated beginning in API level 30.Display.getMetrics()has already worked like this since API level 33.
elegantTextHeight 属性のデフォルト値が true になりました
For apps targeting Android 15 (API level 35), the
elegantTextHeight TextView attribute
becomes true by default, replacing the compact font used by default with some
scripts that have large vertical metrics with one that is much more readable.
The compact font was introduced to prevent breaking layouts; Android 13 (API
level 33) prevents many of these breakages by allowing the text layout to
stretch the vertical height utilizing the fallbackLineSpacing
attribute.
In Android 15, the compact font still remains in the system, so your app can set
elegantTextHeight to false to get the same behavior as before, but it is
unlikely to be supported in upcoming releases. So, if your app supports the
following scripts: Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam,
Odia, Telugu or Thai, test your app by setting elegantTextHeight to true.
elegantTextHeight behavior for apps targeting Android 14 (API level 34) and lower.
elegantTextHeight behavior for apps targeting Android 15.複雑な文字の形状に対する TextView の幅の変更
Android の以前のバージョンでは、複雑なシェーピングを持つ一部の筆記体フォントや言語では、文字が前の文字または次の文字の領域に描画されることがあります。場合によっては、このような文字の開始位置や終了位置が切り詰められていました。Android 15 以降では、TextView はこのような文字に十分なスペースを描画するための幅を割り当て、アプリがクリッピングを防ぐために左側に追加の余白をリクエストできるようにします。
この変更は TextView が幅を決定する方法に影響するため、アプリが Android 15(API レベル 35)以降をターゲットとしている場合、TextView はデフォルトでより多くの幅を割り当てます。この動作を有効または無効にするには、TextView で setUseBoundsForWidth API を呼び出します。
左側の余白を追加すると、既存のレイアウトの位置がずれる可能性があるため、Android 15 以降をターゲットとするアプリでも、デフォルトでは余白は追加されません。ただし、setShiftDrawingOffsetForStartOverhang を呼び出すことで、クリッピングを防ぐためにパディングを追加できます。
次の例は、これらの変更によって、一部のフォントと言語のテキスト レイアウトがどのように改善されるかを示しています。
<TextView android:fontFamily="cursive" android:text="java" />
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
<TextView android:text="คอมพิวเตอร์" />
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
EditText の言語 / 地域対応のデフォルトの行の高さ
In previous versions of Android, the text layout stretched the height of the
text to meet the line height of the font that matched the current locale. For
example, if the content was in Japanese, because the line height of the Japanese
font is slightly larger than the one of a Latin font, the height of the text
became slightly larger. However, despite these differences in line heights, the
EditText element was sized uniformly, regardless
of the locale being used, as illustrated in the following image:
EditText elements that
can contain text from English (en), Japanese (ja), and Burmese (my). The
height of the EditText is the same, even though these languages
have different line heights from each other.For apps targeting Android 15 (API level 35), a minimum line height is now
reserved for EditText to match the reference font for the specified Locale, as
shown in the following image:
EditText elements that
can contain text from English (en), Japanese (ja), and Burmese (my). The
height of the EditText now includes space to accommodate the
default line height for these languages' fonts.If needed, your app can restore the previous behavior by specifying the
useLocalePreferredLineHeightForMinimum attribute
to false, and your app can set custom minimum vertical metrics using the
setMinimumFontMetrics API in Kotlin and Java.
カメラとメディア
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 インターフェースの制限をご覧ください。