これまでのリリースと同様、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
以前は、アプリが 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
アプリがサイレント モードのグローバル状態を変更できるタイミングの変更
Apps that target Android 15 (API level 35) and higher can no longer change the
global state or policy of Do Not Disturb (DND) on a device (either by modifying
user settings, or turning off DND mode). Instead, apps must contribute an
AutomaticZenRule, which the system combines into a global policy with the
existing most-restrictive-policy-wins scheme. Calls to existing APIs that
previously affected global state (setInterruptionFilter,
setNotificationPolicy) result in the creation or update of an implicit
AutomaticZenRule, which is toggled on and off depending on the call-cycle of
those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL) and expects that call to
deactivate an AutomaticZenRule that was previously activated by their owners.
OpenJDK API の変更
Android 15 では、最新の OpenJDK LTS リリースの機能に合わせて Android のコアライブラリを更新する取り組みが引き続き行われています。
これらの変更の一部は、Android 15(API レベル 35)をターゲットとするアプリの互換性に影響する可能性があります。
String Formatting API を変更: 次の
String.format()と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()メソッドは、 theRandom.nextInt()メソッドとは異なる数値シーケンスを返すようになりました。通常、この変更によってアプリの動作が中断されることはありませんが、コードでは
Random.ints()メソッドから生成されたシーケンスがRandom.nextInt()と一致することを想定しないでください。
新しい SequencedCollection API がアプリの互換性に影響する可能性があります
アプリのビルド構成で を更新してcompileSdkを使用すると
Android 15(API レベル 35)
MutableList.removeFirst()とMutableList.removeLast()拡張関数との衝突kotlin-stdlibJava の
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 では、TLS バージョン 1.0 および 1.1 の使用が制限されています。これまではこれらのバージョンは Android で非推奨でしたが、現在は Android 15 をターゲットとするアプリで許可されないようになりました。
バックグラウンド アクティビティの安全な起動
Android 15 protects users from malicious apps and gives them more control over their devices by adding changes that prevent malicious background apps from bringing other apps to the foreground, elevating their privileges, and abusing user interaction. Background activity launches have been restricted since Android 10 (API level 29).
Other changes
- Change
PendingIntentcreators to block background activity launches by default. This helps prevent apps from accidentally creating aPendingIntentthat could be abused by malicious actors. - Don't bring an app to the foreground unless the
PendingIntentsender allows it. This change aims to prevent malicious apps from abusing the ability to start activities in the background. By default, apps are not allowed to bring the task stack to the foreground unless the creator allows background activity launch privileges or the sender has background activity launch privileges. - Control how the top activity of a task stack can finish its task. If the top activity finishes a task, Android will go back to whichever task was last active. Moreover, if a non-top activity finishes its task, Android will go back to the home screen; it won't block the finish of this non-top activity.
- Prevent launching arbitrary activities from other apps into your own task. This change prevents malicious apps from phishing users by creating activities that appear to be from other apps.
- Block non-visible windows from being considered for background activity launches. This helps prevent malicious apps from abusing background activity launches to display unwanted or malicious content to users.
より安全なインテント
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 には、より一貫性のある直感的なユーザー エクスペリエンスを実現するための変更が含まれています。
ウィンドウ インセットの変更
There are two changes related to window insets in Android 15: edge-to-edge is enforced by default, and there are also configuration changes, such as the default configuration of system bars.
エッジ ツー エッジの適用
アプリが 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
安定版の構成
アプリが Android 15(API レベル 35)以上をターゲットにしている場合、Configuration はシステムバーを除外しません。レイアウトの計算に Configuration クラスの画面サイズを使用している場合は、必要に応じて適切な ViewGroup、WindowInsets、WindowMetricsCalculator などのより良い代替手段に置き換える必要があります。
Configuration は API 1 以降で利用可能です。通常は Activity.onConfigurationChanged から取得します。ウィンドウの密度、向き、サイズなどの情報が提供されます。Configuration から返されるウィンドウ サイズの重要な特徴の 1 つは、以前はシステムバーが除外されていたことです。
構成サイズは通常、/res/layout-h500dp などのリソース選択に使用されますが、これは依然として有効なユースケースです。ただし、レイアウトの計算に使用することは常に推奨されていません。その場合は、今すぐ離れてください。ユースケースに応じて、Configuration の使用をより適切なものに置き換える必要があります。
レイアウトの計算に使用する場合は、CoordinatorLayout や ConstraintLayout などの適切な ViewGroup を使用します。システム ナビバーの高さを決定するために使用する場合は、WindowInsets を使用します。アプリ ウィンドウの現在のサイズを知りたい場合は、computeCurrentWindowMetrics を使用します。
この変更の影響を受けるフィールドは次のとおりです。
Configuration.screenWidthDpサイズとscreenHeightDpサイズでシステムバーが除外されなくなりました。Configuration.smallestScreenWidthDpは、screenWidthDpとscreenHeightDpの変更の影響を間接的に受けます。Configuration.orientationは、ほぼ正方形のデバイスでのscreenWidthDpとscreenHeightDpの変更の影響を間接的に受けます。Display.getSize(Point)は、Configurationの変更の影響を間接的に受けます。これは API レベル 30 以降で非推奨になりました。Display.getMetrics()は、API レベル 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 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.
If your app does not target Android 15, some of these changes might not immediately affect you. However, while it's possible for your app to access some non-SDK interfaces depending on your app's target API level, using any non-SDK method or field always carries a high risk of breaking your app.
If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you can't find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.
Android の今回のリリースの変更について詳しくは、非 SDK インターフェースの制限に関する Android 15 での変更点をご覧ください。非 SDK インターフェース全般について詳しくは、非 SDK インターフェースの制限をご覧ください。