2026年のAndroidにおけるフォアグラウンドサービスタイプ: 自分の機能に本当に当てはまるものを選ぶ
Androidのフォアグラウンドサービスタイプの制限に関する実践ガイド — dataSync、mediaPlayback、specialUse、shortService — 強制終了や審査却下を避けて正しいタイプを選ぶ方法。
かつてフォアグラウンドサービスを開始するのは、1行のコードと1つの通知だけで済みました。今は違います。現行のターゲットSDKでは、すべてのフォアグラウンドサービスがマニフェストでタイプを宣言し、対応する権限をリクエストし、いくつかのケースではアプリを公開する前にGoogleに対して自らの存在意義を説明しなければなりません。これは形だけの官僚主義ではありません — タイプごとに異なる存続保証があり、間違ったタイプを選ぶことが、テストでは問題なく動いていた機能が数週間後に実機で静かに強制終了される原因になります。ここでは、Mintlyのフォーカスタイマーが下さざるを得なかった判断を例に、実際にどう選ぶかを説明します。
なぜ「とりあえずフォアグラウンドサービスを始める」が通用しなくなったのか
以前のモデルは寛容でした。startForeground()を呼び、通知を表示すれば、その通知が表示されている限りシステムはおおむね放っておいてくれました。これがフォアグラウンドサービスを悪用の温床にしました — 一度も同期しない「同期」サービス、プロセスを生かし続けるだけの「リスニング」サービス。プラットフォームの答えは、すべてのフォアグラウンドサービスを宣言されたタイプに紐づけることでした。それぞれに固有の権限と、監視なしでどれだけの時間動けるかという契約があります。「信じてください、これは重要です」とはもう言えません。どんな種類の重要さなのかを言い、残りはシステムが強制します。
<service
android:name=".timer.FocusSessionService"
android:foregroundServiceType="specialUse"
android:exported="false">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="active-focus-timer" />
</service>
タイプ宣言を省略すると、現行のターゲットSDKではサービスはそもそも起動しません — startForeground()は警告ではなく例外を投げます。
ほとんどのインディー機能に本当に当てはまるタイプ
厳選されたリストはcamera、microphone、location、phoneCall、mediaPlayback、connectedDeviceのようなケースをカバーしています — それぞれ名前が示す通りに厳密にスコープされ、実際の機能に対応する権限で守られています(FOREGROUND_SERVICE_CAMERAにはCAMERAが必要、といった具合です)。あなたの機能が本当に音声を再生している、あるいはウェアラブルからストリーミングしているなら、タイプは明白で、権限もおそらくすでに持っているものです。
より深く理解する価値がある2つのタイプは、単一のセンサーに対応しないものです。dataSyncとspecialUseです。
dataSyncは明確な終着点のあるバックグラウンド転送のためのものです — バックアップのアップロード、リモート更新の取得。休止状態ではありません。Android 15以降、dataSyncとmediaProcessingのサービスは、24時間の移動ウィンドウでおよそ6時間の累積実行時間予算を得ます。それを超えるとシステムはService.onTimeout()を呼び出し、強制停止する前に片付けるための短い猶予を与えます。これは、そのタイプが想定しているもの — 終わるはずの転送 — にとっては妥当な取引であり、無期限にそこに居座ることを意図した何かには不向きです。
specialUse: リストにない全てのためのタイプ
25分のフォーカスタイマーは、データ同期でも、メディア再生でも、センサーに紐づいたものでもありません。まさにspecialUseが埋めるために存在する隙間です — 本当に時間が限られていてユーザーが開始するものの、名前付きのカテゴリのどれにも当てはまらないフォアグラウンドサービス。落とし穴は、単に宣言して済ませられないことです。マニフェストの<property>タグは、サービスが何をするかを説明するサブタイプ文字列を必要とし、Google Playのアプリ審査はその文字列を読みます。実際には偽装されたデータ同期や生かし続けるためのハックであるものにspecialUseを宣言すると、まさにそうしたミスマッチがローンチ後ではなく審査中にフラグを立てられます。
Mintlyの場合、サブタイプはactive-focus-timerで、Play Consoleのフォアグラウンドサービス宣言フォームも同じことを平易な言葉で述べています — ユーザーが開始し、積極的に見守っている、特定の時刻に終わる実行中のセッション。これは真実であるがゆえに正当化しやすいケースです。サービスが何をするかについて正直な一行の説明を書くことは、審査の精査を回避できるタイプを探そうとするよりも良い時間の使い方です。
shortService: セッションのためではなく、短い作業のために作られた
もう一つ知っておくべきタイプはshortServiceです。大きなエクスポートを書き出す、一回限りのクリーンアップを実行するといった、何かを終わらせるのに数分しか必要としないフォアグラウンドサービスのためのもので、ユーザーがWorkManagerの高速化ジョブのコールドスタートを我慢できる時間よりも短い作業を対象としています。約3分という厳格な実行時間の上限があり、システムはそれを超えて交渉しません。このタイプが存在するのは、短時間の作業が必要以上に長い猶予を得るためにdataSyncやspecialUseを悪用するのをやめさせるためです。タスクが予測可能に3分未満で終わるなら、これが使うべき正直なタイプです。時々長引くなら、それは間違ったタイプであり、テストではなく本番環境でそれを知ることになります。
タイプを間違えることは本番環境のバグであり、lintの警告ではない
宣言するタイプは、自信がない場合にAndroidが丁寧に無視してくれるメタデータではありません。1日8時間動くものにdataSyncを宣言すれば、実行途中でタイムアウトになります — その後アプリが正しく検知して回復しなければならない状態であり、そうしなければユーザーは説明もなく止まった機能を見ることになります。正直なサブタイプなしにspecialUseを宣言すれば、Playの審査が更新を丸ごと却下することもあります。これは、最初から正しいタイプを選ぶのにかかる10分よりもはるかに悪いローンチの遅延です。
判断は2つの問いに集約されます。このサービスはcameraやmediaPlaybackのような実際の機能に対応しているか? そうでなければ、作業は自然に分単位で区切られているか(shortService)、明確な終わりのある時間単位か(dataSync)、それとも終わりが決まっていないがユーザーが開始し積極的に見守られているか(specialUse、正直に宣言したもの)? マニフェストのエントリを書く前にこれらに答えてください。クラッシュレポートが出てきた後ではなく。タイプシステムは一度学べば面倒なだけで、その後はプラットフォームについての単なる事実になります — Android 16のLive Updatesが、Mintlyのタイマーサービスのフォアグラウンドサービスタイプを最初から正しく選ぶ必要性を置き換えるのではなく、その上に乗っているのと同じように。
// 関連記事
ジャーナルの他の記事
Mintly を作る: Android がプロセスを殺そうとする中で集中タイマーを正確に保つ
動作中の Pomodoro タイマーは、一度きりのリマインダーより難しい信頼性の問題を抱えている。フォアグラウンドサービスと壁時計ベースの終了時刻で、Mintly が Doze・プロセス終了・画面オフ中のずれをどう乗り越えたかを解説する。
Android の In-App Review API:うっとうしくならずに評価を頼む方法
Google の In-App Review API の実践ガイド。実際の仕組み、表示すべきタイミング、そしてありがちな『評価してください』ポップアップが Play ストアの評価を静かに損なっている理由。
Androidのアプリショートカットとクイック設定タイル:アプリを開かずに水分補給を記録する
AndroidのダイナミックShortcutManager APIとTileServiceの実践ガイド — ワンタップの操作でアプリ起動を完全にスキップする方法と、多くの実装が陥りがちな落とし穴について。