Android 15 Betaバージョンリリース!開発者は新しいバージョン制限にどう対応するか?
Android 15が最近Beta版としてリリースされました
新バージョンは VanillaIceCream バニラアイスクリーム
と呼ばれています
以下はロードマップです:
詳細なスケジュールは:公式サイト を参照してください
-
クラス
ApplicationInfo
において
過去にはFLAG_STOPPED
というタグが存在しました
その動作は現在アプリが停止状態
であるかどうかを示していました
過去の停止状態
の判定は、ユーザーがアプリを強制停止したときに設定され、アプリはこの状態を保持しました。 -
一方、システムがアプリを
停止状態
から外すには
過去にはユーザーがアプリをクリックして開く
、または一部のインタラクティブウィンドウを開くことで状態を変更できました↪ ここに公式の
原文
があります:
directly launching the app or indirectly interacting with the app.
(through the sharesheet or a widget, selecting the app as live wallpaper, etc.)
Android 14ではユーザーがアプリをクリックして開く
と一部のインタラクティブウィンドウを間接的に開く
ことが可能でした
例としてsharesheet
、ウィジェット
、ライブ壁紙として選択
などが挙げられています - 最新の
Android 15
システムにおけるFLAG_STOPPED
には以下の変更と拡張があります。
- 現在、システムが
FLAG_STOPPED
と判定した場合、すべてのpending intents
の操作が停止されます - システムが
FLAG_STOPPED
から離れる
と判断した場合、ACTION_BOOT_COMPLETED
ブロードキャストが送信されます
公式には、このブロードキャストを通じて開発者が pending intent を復元できると述べています。
↪ ここに公式の
原文
説明があります。15におけるFLAG_STOPPED
判定の調整について:
Apps should only be removed from the stopped state through direct or indirect user action.
つまり、直接的または間接的なユーザーアクションのみがシステムによって停止状態
と判定されることを変更します - 現在、システムが
-
上記から、この状態の判定がより厳格になったことが理解できます
↪ ただし、上記の原文には
indirect user action
が具体的に何を指すのか明確に記載されていません。
今後の参考にしてください - さらに、
Application StartInfo.wasForceStopped()
メソッドを使用して上記の状態を判定できます。
-
公式はRAMの利用戦略を最適化しました
過去にはAndroidは4 KBメモリページサイズ
のみをサポートしていました
現在は16 KBページサイズ
に引き上げられました
来年にはGoogle Playに導入される予定です(15には既にありますが、その時点で16KBコンパイルのアプリが強制されるかは不明です ✨)
ページサイズの引き上げは主にRAM集約型の作業
を最適化し、より効率的に使用できるようにするためです
これはソフトウェアの最適化に関するものです
主に将来メーカーがより大きく、より高性能なRAMを開発する
際にアプリがスムーズに動作し、互換性を持つようにするためです
✅ページサイズ
はメモリ内の操作単位を表すもので、通常は2の累乗です。例:2KB、4KB、8KBなど。 -
アプリ開発者
への影響:
↪ Ndkを使用してコンパイルする場合、またはSDKを直接または間接的に使用してコンパイルする場合、16 KBページサイズ
のアプリを再設定する必要があるかもしれません
↪短期
的にはプロジェクトに大きな影響はないでしょう
↪将来
Google Playに正式にリリースされると、16 KBページサイズ
に関連する問題が発生する可能性があります
✅ 互換性の問題
が発生した場合は、公式サイトを参考にしてコンパイル方法を調整してください
Android Studio
内のAPK Analyzer
を使用して、ネイティブコードが使用されているかどうかを判断できます(または逆コンパイル
して確認)
↪ apkをAndroid Studioにドラッグします
↪ libフォルダに任意の.so
ファイル(共有オブジェクト)が表示されるか確認します
表示される場合、アプリはネイティブコードでコンパイルされています
libや.so
が表示されない場合は、ネイティブコードが使用されていない可能性があります
✅ 公式によると、ネイティブコードを使用している場合
は、16KBデバイス
にアプリを再構築する必要があります。
以下は初期判断の参考です:
↪ 任意のC/C++(ネイティブ)コードを使用している場合、通常はNDK関連やJNIなどを含む。
↪ 任意のサードパーティライブラリがネイティブライブラリを使用している場合。
↪ 任意のサードパーティのビルダーがネイティブライブラリを使用している場合。
- 下図は
16 KBページサイズ
の機能が最適化された後の
システムパフォーマンスの向上を示しています
この機能は、アプリを隠すスペースやアプリロックに似た機能を追加します
アプリを開くにはパスワードが必要です
ただし、公式には現在バグがあるとされています
エミュレーターでもこの機能は見つかりませんでした
しかし、公式はこの機能がアプリの可視性を制限することを述べています
プライベートスペース内のアプリは可視性が制限されているため、
後でこの機能が使用可能になったときに、自分のアプリを入れて問題がないか確認できます
例:QueryAllPackagesPermission`の機能が予期通りに動作するかどうか不明です
その時に試してみてください
-
Android 14と同様に、古いAPIを使用して脆弱性を悪用するのを防ぐためです
Android 15
では、ターゲットが24以上でないとインストールできません
インストールできない場合はINSTALL_FAILED_DEPRECATED_SDK_VERSION
と表示されます
以下のコマンドを使用して、規定に合わないapkをインストールできますadb install --bypass-low-target-sdk-block FILENAME.apk
UI/UX調整
-
開発者オプションから
予測バックアニメーション
を削除
開発者がアプリ内で設定できるようにしました<application ... android:enableOnBackInvokedCallback="true" ... > ... </application>
✅
予測バックアニメーション
とは何かを確認する :参考
日常的に廃止される一部のAPI:
API廃止の参考
- BOOT_COMPLETEDブロードキャスト時に以下のフォアグラウンドサービスを起動することを禁止
- dataSync
- camera
- mediaPlayback
- phoneCall
- mediaProjection
- microphone
↪ 強制的に起動するとForegroundServiceStartNotAllowedException
がスローされます
-
dataSync
に対する最終審判
↪ dataSyncのサービスは現在、24時間内に6時間しか実行できません。時間が来るとシステムはService.onTimeout(int, int)
を呼び出します
この時、タイムアウトを受け取ってから数秒以内にService.stopSelf()
を呼び出す必要があります
↪ 時間が来てもstopSelf
を呼び出さない場合、次のエラーが発生します
A foreground service of ##fgs_type did not stop within its timeout: ##component_name.
↪ システムがService.onTimeout(int, int)
を呼び出すと、そのサービスはもはやフォアグラウンドサービスとは見なされません
↪ 現在のbeta2バージョンではスローされるエラーはANR
と見なされますが、後のバージョンではexception
に変更されます。
↪ 上記の制限はすべてのdataSyncサービスに適用されます。例えば、24時間内にすでに4時間dataSyncを実行している場合、他のdataSyncは残り2時間しか実行できません ↪ または公式が推奨する他の方法に移行することを検討してください:代替案 -
新しいフォアグラウンドサービスタイプの追加:mediaProcessing
↪ このタイプは上記のdataSyncと同じルールが適用されます
↪mediaProcessing
のサービスは現在、24時間内に6時間しか実行できません。時間が来るとシステムはService.onTimeout(int, int)
を呼び出します
この時、タイムアウトを受け取ってから数秒以内にService.stopSelf()
を呼び出す必要があります
↪ システムがService.onTimeout(int, int)
を呼び出すと、そのサービスはもはやフォアグラウンドサービスとは見なされません
↪ 公式が提供する代替案は上記のdataSyncとは異なります:代替案 -
上記のタイプのタイマーをリセットするには、ドキュメントに記載されているように
ユーザーがアプリを前景に移動する必要があります
-
特殊なケースを使用することもできます
- こちらをクリック
- ただし、公式には説明を提供し、審査を通過する必要があります
- 以前は、SYSTEM_ALERT_WINDOWを使用してフォアグラウンドサービスを起動することができ、アプリがバックグラウンドにあっても動作しました
現在は新しいステップが必要です:TYPE_APPLICATION_OVERLAY
を使用してオーバーレイウィンドウを起動し、それが可視である必要があります
↪ 上記の新しい要件を満たさない場合、ForegroundServiceStartNotAllowedException
がスローされます。
- ターゲットSDKがAndroid 15以上のアプリは、
おやすみモードDo Not Disturb (DND)
のグローバルステート
やポリシー
の設定をサポートしなくなります。
↪ 以前setInterruptionFilter(INTERRUPTION_FILTER_ALL)
を使用して設定していたアプリに影響します。
- Android 15では、この変更に伴いAPIの使用方法が調整されました。使用する場合は注意が必要です。
以下の関数で文字列をフォーマットする際に例外が追加されました。
- String.format(String, Object[])
- String.format(Locale, String, Object[])
- Formatter.format(String, Object[])
- Formatter.format(Locale, String, Object[])
↪ $0
を誤用した場合、IllegalFormatArgumentIndexException
: Illegal format argument index = 0 がスローされます。
//work
val formattedString = String.format("Name: %1$s, Age: %2$d", name, age);
//exception
val formattedString = String.format("Name: %0$s, Age: %1$d", name, age);
- このissueに対応して、
Random
クラスが調整されました。 現在、Random.ints()
はRandom.nextInt()
と同じ値を返さなくなりました。 したがって、現在では両者が==
であることを期待すべきではありません。- Random.ints(long)
- Random.ints(long, int, int)
- Random.ints(int, int)
- Random.ints()
- Android 10以降、バックグラウンドでのアクティビティ起動は制限されていますが、
Android 15
ではさらに制御が追加され、悪意のあるバックグラウンドアプリケーション
が他のアプリケーションを前面に持ってくることを防止します。 -
現在、新しいフラグが追加され、バックグラウンドのアクティビティが他のアプリのアクティビティを開くことができなくなります。
<application android:allowCrossUidActivitySwitchFromBelow="false" >
実際の変更としては、開こうとしているアクティビティとスタックの最上層のアプリの
UIDが一致しない
場合、開くことができません。 ↪ これはアプリが他の異なるアプリを開くのを防ぐためです。 - その他のバックグラウンドでのアクティビティ起動に関する制限
- 現在、
PendingIntent
はデフォルトでバックグラウンドアクティビティの起動をブロック
します。
- 現在、
- この調整はユーザーエクスペリエンスの改善を目的としています。以下に概要を示します。
-
Edge-to-edge enforcement
:エッジからエッジまでの強制実行。Android 15では画面の端に強制的に内縮されます。 ただし、material 3
を使用している場合は影響を受けません。実際にmaterial 3を使用しているアプリ
は元のUIと一致します。
他のUIが影響を受ける可能性がある場合は注意が必要です。
↪ 上記の3番目の画像は、windowInsets.getInsetsなどを使用して調整した後のものです。
またはmaterial 3を使用することもできます。 -
elegantTextHeight attribute defaults to true
:デフォルトでelegantTextHeight属性がtrue
になります。
Stable configuration
:configurationに関連する動作の調整。画面の向きやシステムバーのサイズの判断に影響する可能性があります。
こちらをクリックして詳細を確認Locale-aware default line height for EditText
:異なる言語に応じてEditTextの高さが異なる可能性があります。
✅ 変更後の状態が受け入れ可能かどうか確認してください。
取り消すには、useLocalePreferredLineHeightForMinimum
属性をfalseに設定します。TextView width changes for complex letter shapes
:複雑な文字のためにデフォルトの文字幅の割り当てルールが調整されました。
複雑な文字により多くのスペースを提供します。
✅無効化/有効化
したい場合は、setShiftDrawingOffsetForStartOverhang
属性を設定します。
-
- その他のUI/UXの詳細については、こちらのより完全なリファレンスを参照してください:こちらをクリック
オーディオフォーカス (audio focus)
をリクエストするには、現在トップアプリ
またはオーディオ関連のフォアグラウンドサービス
である必要があります。そうでない場合、AUDIOFOCUS_REQUEST_FAILEDが返されます。- 現在
オーディオ関連のフォアグラウンドサービス
と見なされるものは以下の通りです:- mediaPlayback
- camera
- microphone
- phoneCall
✅ オーディオフォーカス (audio focus) を学ぶ こちらをクリック
- 日常的なバージョン更新には以下が含まれます:こちらをクリック
✅非SDK
:Javaのメソッドが含まれます。これらのインターフェースはSDKの内部実装の詳細であり、予告なしに変更される可能性があります。