これまでのリリースと同様、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_COMPLETED
broadcast receivers launching foreground services - Restrictions on starting foreground services while an app holds the
SYSTEM_ALERT_WINDOW
permission
Data sync foreground service timeout behavior
对于以 Android 15(API 级别 35)或更高版本为目标平台的应用,Android 15 为 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 小时时间。 - 请使用替代 API,而不是使用
dataSync
前台服务。
如果您的应用的 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
mediaProcessing
services 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
mediaProcessing
foreground 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
mediaProcessing
foreground 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
接收器不能启动
以下类型的前台服务:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(自 Android 14 起,microphone
就受到此限制)
如果 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
アプリがサイレント モードのグローバル ステータスを変更できるタイミングの変更
以 Android 15(API 级别 35)及更高版本为目标平台的应用无法再更改设备上的勿扰 (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]);
言語コードの処理の変更:
Locale
API を使用する場合、ヘブライ語、イディッシュ語、インドネシア語の言語コードは、廃止された形式(ヘブライ語:iw
、イディッシュ語:ji
、インドネシア語:in
)に変換されなくなりました。これらの言語 / 地域の言語コードを指定する場合は、代わりに ISO 639-1 のコード(ヘブライ語:he
、イディッシュ語:yi
、インドネシア語:id
)を使用してください。乱数 int シーケンスの変更: 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
の拡張関数ではなく、新しいList
API に静的に解決します。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 の他のメソッドとの競合
既存のタイプに新しいメソッドが追加されました(
List
、Deque
など)。これらの新しいメソッドは、他のインターフェースやクラスの同じ名前と引数型のメソッドと互換性がない場合があります。メソッド シグネチャの競合と非互換性がある場合、javac
コンパイラはビルド時エラーを出力します。次に例を示します。エラーの例 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これらのビルドエラーを修正するには、これらのインターフェースを実装するクラスで、互換性のある戻り値の型を持つメソッドをオーバーライドする必要があります。例:
@Override public Object getFirst() { return List.super.getFirst(); }
セキュリティ
Android 15 では、システムのセキュリティを強化し、悪意のあるアプリからアプリとユーザーを保護するための変更が加えられています。
安全なバックグラウンド アクティビティの起動
Android 15 では、悪意のあるアプリからユーザーを保護し、より細かく 悪意のあるバックグラウンド アプリが悪意のあるアクティビティを 他のアプリをフォアグラウンドで動作させる、権限昇格させる、アプリを悪用する です。バックグラウンド アクティビティの起動は、それ以降、 Android 10(API レベル 29)。
スタックの最上位の UID と一致しないアプリによるアクティビティの起動をブロックする
悪意のあるアプリは、同じタスク内で別のアプリのアクティビティを起動し、
そのアプリであるかのように見せかけます。この「タスク」は、
ハイジャック」現在のバックグラウンド起動の制限をバイパスできます。
同じ表示タスク内で発生します。このリスクを軽減するため、Android 15 では
スタックの最上位の UID と一致しないアプリの起動をブロックするフラグ
できます。アプリのすべてのアクティビティをオプトインするには、
allowCrossUidActivitySwitchFromBelow
属性を AndroidManifest.xml
ファイル内で指定する必要があります。
<application android:allowCrossUidActivitySwitchFromBelow="false" >
次の条件がすべて満たされている場合、新しいセキュリティ対策は有効です。
- リリースを実行するアプリは Android 15 をターゲットとしています。
- タスクスタックの一番上にあるアプリは Android 15 をターゲットとしています。
- 表示されているアクティビティはすべて、新しい保護設定にオプトインしています。
セキュリティ対策が有効になっている場合、アプリは 最後に表示されたアプリ(ユーザーが自身のタスクを完了した場合)
その他の変更点
UID マッチングの制限以外にも、次のような変更があります。 含まれるもの:
PendingIntent
のクリエイターを変更してバックグラウンド アクティビティの起動をブロックするよう変更する デフォルトです。これにより、アプリが誤って IP アドレスをPendingIntent
: 悪意のある人物によって悪用されるおそれがあります。PendingIntent
の送信者がない限りアプリをフォアグラウンドに戻さない 許可します。この変更は、悪意のあるアプリによって バックグラウンドでアクティビティを開始する機能。デフォルトでは、アプリが クリエイターが許可しない限り、タスクスタックをフォアグラウンドに移すことができる バックグラウンド アクティビティの起動権限がある、または送信者にバックグラウンド アクティビティがある できます。- タスクスタックのトップ アクティビティがタスクを終了する方法を制御する。もし 上位のアクティビティがタスクを終了すると、Android は 最後のアクティブな状態。さらに、トップ以外のアクティビティがそのタスクを完了すると、Android は ホーム画面に戻ります。このノントップ スレッドの できます。
- 他のアプリから自分のアクティビティに任意のアクティビティを起動できないようにする タスクです。この変更により、悪意のあるアプリがユーザーをフィッシング攻撃から 他のアプリからと思われるアクティビティ
- 非表示のウィンドウがバックグラウンド アクティビティの対象とみなされないようにブロックする 。これにより、悪意のあるアプリによるバックグラウンドの不正使用を防ぐことができます 望ましくないコンテンツや悪意のあるコンテンツをユーザーに表示する。
より安全なインテント
Android 15 引入了新的可选安全措施,以提高 intent 的安全性和稳健性。这些变更旨在防止潜在的漏洞以及恶意应用可能利用的 intent 滥用行为。Android 15 对 intent 的安全性进行了两项主要改进:
- 与目标 intent 过滤器匹配:定位到特定组件的 intent 必须与目标的 intent 过滤器规范完全匹配。如果您发送 intent 来启动其他应用的 activity,目标 intent 组件需要与接收 activity 声明的 intent 过滤器保持一致。
- intent 必须具有操作:没有操作的 intent 将不再与任何 intent 过滤器匹配。这意味着,用于启动 activity 或服务的 intent 必须具有明确定义的操作。
如需检查您的应用对这些更改的响应方式,请在应用中使用 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 を搭載したデバイスでは、アプリはデフォルトで端から端まで表示されます。
これは互換性を破る変更であり、アプリの 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)をターゲットとする前後のアプリと、インセットを適用する前後のアプリを示しています。
アプリがすでにエッジツーエッジの場合に確認すべき点
アプリがすでにエッジツーエッジで、インセットを適用している場合は、以下のシナリオを除き、ほとんど影響を受けません。ただし、影響を受けていないと思われる場合でも、アプリをテストすることをおすすめします。
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#enforceStatusBarContrast
R.attr#navigationBarColor
(3 ボタン ナビゲーション用、アルファ 80%)Window#isStatusBarContrastEnforced
Window#setNavigationBarColor
(3 ボタン ナビゲーション用、アルファ 80%)Window#setStatusBarContrastEnforced
次の API は非推奨で、無効になっています。
R.attr#navigationBarColor
(ジェスチャー ナビゲーション用)R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#setDecorFitsSystemWindows
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#setNavigationBarColor
(ジェスチャー ナビゲーション用)Window#setNavigationBarDividerColor
Window#setStatusBarColor
安定した構成
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.screenWidthDp
andscreenHeightDp
sizes no longer exclude the system bars.Configuration.smallestScreenWidthDp
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
.Configuration.orientation
is indirectly affected by changes toscreenWidthDp
andscreenHeightDp
on 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
Android 15(API レベル 35)をターゲットとするアプリの場合、elegantTextHeight
TextView
属性はデフォルトで true
になります。これにより、デフォルトで使用されるコンパクトなフォントが、読みやすく大きな縦方向の測定値を持つスクリプトに置き換えられます。コンパクト フォントは、レイアウトの分割を防ぐために導入されました。Android 13(API レベル 33)では、fallbackLineSpacing
属性を使用してテキスト レイアウトの垂直方向の高さを伸ばすことで、このような分割の多くを防ぐことができます。
Android 15 では、コンパクト フォントは引き続きシステムに残るため、アプリで elegantTextHeight
を false
に設定して以前と同じ動作を実現できますが、今後のリリースでサポートされる可能性は低いです。そのため、アプリがアラビア語、ラオス語、ミャンマー語、タミル語、グジャラート語、カンナダ語、マラヤーラム語、オディア語、テルグ語、タイ語のスクリプトをサポートしている場合は、elegantTextHeight
を true
に設定してアプリをテストします。
複雑な文字の形状で TextView の幅が変更される
Android の以前のバージョンでは、複雑なシェーピングを持つ一部の筆記体フォントや言語では、文字が前の文字または次の文字の領域に描画されることがあります。場合によっては、このような文字の開始位置や終了位置が切り詰められていました。Android 15 以降では、TextView
はこのような文字に十分なスペースを描画するための幅を割り当て、アプリがクリッピングを防ぐために左側に追加の余白をリクエストできるようにします。
この変更は TextView
が幅を決定する方法に影響するため、アプリが Android 15(API レベル 35)以降をターゲットとしている場合、TextView
はデフォルトでより多くの幅を割り当てます。この動作を有効または無効にするには、TextView
で setUseBoundsForWidth
API を呼び出します。
左側の余白を追加すると、既存のレイアウトの位置がずれる可能性があるため、Android 15 以降をターゲットとするアプリでも、デフォルトでは余白は追加されません。ただし、setShiftDrawingOffsetForStartOverhang
を呼び出すことで、クリッピングを防ぐためにパディングを追加できます。
次の例は、これらの変更によって、一部のフォントと言語のテキスト レイアウトがどのように改善されるかを示しています。
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:
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:
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 インターフェースの制限をご覧ください。