フォアグラウンド サービス

フォアグラウンド サービスは、ユーザーが認識できるオペレーションを実行します。

フォアグラウンド サービスにステータスバーが表示される 通知を設定して、 アプリがフォアグラウンドでタスクを実行していて、システム リソースを消費しています。

フォアグラウンド サービスを使用するアプリの例としては、次のようなものが挙げられます。

  • フォアグラウンド サービスで音楽を再生する音楽プレーヤー アプリ。通知 現在再生中の曲が表示されます。
  • フォアグラウンド サービスでのユーザーのランニングを、 ユーザーの許可を得る場合などです通知に距離が表示されることがあります ユーザーが現在のフィットネス セッション中に移動したデータ。

アプリがタスクを実行する必要がある場合のみフォアグラウンド サービスを使用する ユーザーが直接やり取りしていないときでも、 クリックします。アクションの重要度が低い場合は、 通知の場合は、背景を作成するとともに、 タスクを使用してください。

このドキュメントでは、フォアグラウンド サービスの使用に必要な権限について説明します。 フォアグラウンド サービスを開始してバックグラウンドから削除する方法を説明します。また、 特定のユースケースをフォアグラウンド サービスのタイプに関連付ける方法について説明します。 フォアグラウンド サービスの開始時に有効になるアクセス制限 アプリがバックグラウンドで動作している 関数を検出できます

ユーザーがデフォルトで通知を閉じることができる

Android 13(API レベル 33)以降では、ユーザーは通知を閉じることができます。 関連付けられているデフォルトの設定です。これを行うには、ユーザーはスワイプ操作を行います。 操作します。これまでは通知が フォアグラウンド サービスが停止または削除されない限り、閉じられない 使用できます。

ユーザーが通知を非表示にできないようにするには、 setOngoing()true メソッド Notification.Builder を使用して通知を作成する際に、

通知をすぐに表示するサービス

フォアグラウンド サービスが次のいずれかの特性を持つ場合、 サービス開始直後にシステムが関連する通知を表示する。 Android 12 以降を搭載したデバイスでも、以下のようになります。

Android 13(API レベル 33)以降では、ユーザーが 通知権限 フォアグラウンド サービスに関連する通知が タスク マネージャー 通知ドロワーにも表示されません。

マニフェストでフォアグラウンド サービスを宣言する

アプリのマニフェストで、アプリの各フォアグラウンド サービスを宣言します <service> を使用 要素です。サービスごとに android:foregroundServiceType 属性 サービスが実行する処理の種類を宣言します。

たとえば、アプリが音楽を再生するフォアグラウンド サービスを作成する場合、 は、次のようにサービスを宣言します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
  <application ...>

    <service
        android:name=".MyMediaPlaybackService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="false">
    </service>
  </application>
</manifest>

複数のタイプがサービスに適用される場合は、| で区切ってください。 演算子を使用します。たとえば、カメラとマイクを使用するサービスが 次のように宣言します。

android:foregroundServiceType="camera|microphone"

フォアグラウンド サービスの権限をリクエストする

Android 9(API レベル 28)以降をターゲットとし、フォアグラウンド サービスを使用するアプリ リクエストを FOREGROUND_SERVICE をアプリ マニフェストに追加します。次のコード スニペットをご覧ください。これは通常の 権限があるため、システムは リクエスト元のアプリに自動的に付与されます。

また、アプリが API レベル 34 以降をターゲットとしている場合は、 フォアグラウンド サービスの作業内容に応じた適切な権限タイプ できます。各フォアグラウンド サービス タイプ 権限タイプがあります。たとえば、アプリが 使用する場合は、カメラと API の両方をリクエストする必要があります。 FOREGROUND_SERVICE および FOREGROUND_SERVICE_CAMERA 付与できます。これらはすべて通常の権限なので、システムは 自動的に検出されます。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>

    <application ...>
        ...
    </application>
</manifest>

フォアグラウンド サービスの前提条件

Android 14(API レベル 34)以降では、フォアグラウンド サービスを起動すると、 サービスタイプに応じて特定の前提条件がチェックされます。たとえば location タイプのフォアグラウンド サービスを起動しようとすると、 アプリに ACCESS_COARSE_LOCATION または ACCESS_FINE_LOCATION 権限。そうでない場合、システムは SecurityException

このため、必要な前提条件を満たしていることを確認する必要があります。 開始する必要があります。フォアグラウンド サービス type のドキュメント に、各フォアグラウンド サービス タイプに必要な前提条件の一覧を示します。

フォアグラウンド サービスを開始する

サービスをフォアグラウンド サービスとして実行するようシステムにリクエストする前に、 確認します。

Kotlin

val intent = Intent(...) // Build the intent for the service
context.startForegroundService(intent)

Java

Context context = getApplicationContext();
Intent intent = new Intent(...); // Build the intent for the service
context.startForegroundService(intent);

サービス内で、通常は onStartCommand() で、 実行されていることを示します。これを行うには、 ServiceCompat.startForeground() (androidx-core 1.12 以降で利用可能)。このメソッドは、 parameters:

これらの型は、マニフェストで宣言されている型のサブセットである可能性があります。 決定しますサービスタイプを追加する必要がある場合は startForeground() を再度呼び出すことができます。

たとえば、フィットネス アプリがランニング トラッカー サービスを実行しているとします。 location 情報が必要ですが、メディアの再生に必要な場合と必要ない場合があります。マイページ マニフェストで locationmediaPlayback の両方を宣言する必要があります。もし ユーザーがランニングを開始して、位置情報を追跡することのみが必要な場合、アプリは次の呼び出しを行う必要があります。 startForeground() という名前で ACCESS_FINE_LOCATION 権限だけを渡します。その後、 ユーザーが音声の再生を開始したい場合は、もう一度 startForeground() を呼び出して、 すべてのフォアグラウンド サービス タイプ(この場合は、 ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK)。

以下に、カメラのフォアグラウンド サービスを起動する例を示します。

Kotlin

class MyCameraService: Service() {

  private fun startForeground() {
    // Before starting the service as foreground check that the app has the
    // appropriate runtime permissions. In this case, verify that the user has
    // granted the CAMERA permission.
    val cameraPermission =
            PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA)
    if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) {
        // Without camera permissions the service cannot run in the foreground
        // Consider informing user or updating your app UI if visible.
        stopSelf()
        return
    }

    try {
        val notification = NotificationCompat.Builder(this, "CHANNEL_ID")
            // Create the notification to display while the service is running
            .build()
        ServiceCompat.startForeground(
            /* service = */ this,
            /* id = */ 100, // Cannot be 0
            /* notification = */ notification,
            /* foregroundServiceType = */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
            } else {
                0
            },
        )
    } catch (e: Exception) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
                && e is ForegroundServiceStartNotAllowedException) {
            // App not in a valid state to start foreground service
            // (e.g. started from bg)
        }
        // ...
    }
  }
}

Java

public class MyCameraService extends Service {

    private void startForeground() {
        // Before starting the service as foreground check that the app has the
        // appropriate runtime permissions. In this case, verify that the user
        // has granted the CAMERA permission.
        int cameraPermission =
            ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        if (cameraPermission == PackageManager.PERMISSION_DENIED) {
            // Without camera permissions the service cannot run in the
            // foreground. Consider informing user or updating your app UI if
            // visible.
            stopSelf();
            return;
        }

        try {
            Notification notification =
                new NotificationCompat.Builder(this, "CHANNEL_ID")
                    // Create the notification to display while the service
                    // is running
                    .build();
            int type = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
            }
            ServiceCompat.startForeground(
                    /* service = */ this,
                    /* id = */ 100, // Cannot be 0
                    /* notification = */ notification,
                    /* foregroundServiceType = */ type
            );
        } catch (Exception e) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
                    e instanceof ForegroundServiceStartNotAllowedException
            ) {
                // App not in a valid state to start foreground service
                // (e.g started from bg)
            }
            // ...
        }
    }

    //...
}

フォアグラウンドからサービスを削除する

サービスをフォアグラウンドから削除するには、呼び出します。 stopForeground()。 このメソッドは、ステータスバーを削除するかどうかを示すブール値を受け取ります。 表示されます。サービスは引き続き実行されます。

フォアグラウンドで実行中のサービスを停止すると、 削除されます。

フォアグラウンド サービスを実行しているアプリをユーザーが自発的に停止した場合の処理

通知ドロワーの下部には、通知内容を示すボタンがあり、
    実行中のアプリの数を確認できます[
    このボタンをクリックすると、さまざまなアプリの名前が記載されたダイアログが表示されます。「
    停止ボタンは各アプリの右側
図 1. タスク マネージャーのワークフローを Android 13 以降を搭載している。

Android 13(API レベル 33)以降では、ユーザーは 通知ドロワー フォアグラウンド サービスを実行しているアプリは、 ターゲット SDK バージョン。このアフォーダンスは タスク マネージャー: 実行中のアプリのリストが表示されます。 フォアグラウンドサービスを実行している インスタンスについて見てみましょう

このリストには、[有効なアプリ] というラベルが付きます。 各アプリの横には [停止] ボタンがあります。図 1 は、 以下を搭載したデバイスでのタスク マネージャーのワークフロー Android 13。

ユーザーがブラウザの [停止] ボタンを押すと、 タスク マネージャーを起動すると、次のアクションが実行されます。

  • アプリがメモリから削除されます。アプリ全体が停止します。 実行中のフォアグラウンド サービスだけではありません。
  • システムがアプリのアクティビティのバックスタックを削除します。
  • メディアの再生が停止します。
  • フォアグラウンド サービスに関連付けられた通知は削除されます。
  • アプリは履歴に残ります。
  • スケジュールされたジョブは、スケジュールされた時刻に実行されます。
  • アラームは、設定した時刻または時間枠に鳴ります。
で確認できます。

ユーザーがアプリを停止している間と停止した後に、アプリが想定どおりに動作することをテストするには、 ターミナル ウィンドウで次の ADB コマンドを実行します。

adb shell cmd activity stop-app PACKAGE_NAME

除外

特定のタイプのアプリには、以下のセクションで説明するいくつかのレベルの除外が適用されます。

除外は、プロセス単位ではなくアプリ単位で適用されます。アプリ内の 1 つのプロセスが除外されると、そのアプリ内の他のプロセスもすべて除外されます。

タスク マネージャーにまったく表示されないようにする

以下のアプリはフォアグラウンド サービスを実行できますが、 タスク マネージャー:

  • システムレベルのアプリ
  • 緊急情報サービスアプリ(つまり、ROLE_EMERGENCY ロールを持つアプリ)
  • デモモードのデバイス

ユーザーによる停止対象からの除外

次の種類のアプリがフォアグラウンド サービスを実行すると、 タスク マネージャーに表示されるが、コマンドの横に [停止] ボタンがない ユーザーがタップするアプリ名:

フォアグラウンド サービスの代わりに専用 API を使用する

多くのユースケースでは、作業に使用できるプラットフォーム API や Jetpack API があります フォアグラウンド サービスを使用する場合があります。適切な 使用する場合は、ほとんどの場合、フォアグラウンド API ではなく、 あります。専用 API により、ユースケース固有の追加機能が提供されることがよくあります。 独自の機能を構築できます。たとえば Bubbles API が複雑な UI ロジックを処理し、 チャットふきだし機能を実装する必要があるメッセージ アプリ。

フォアグラウンド サービスのタイプに関するドキュメント フォアグラウンド サービスの代わりに使用できます。

バックグラウンドからのフォアグラウンド サービスの起動に関する制限

Android 12 以降をターゲットとするアプリは、フォアグラウンドを開始できない アプリがバックグラウンドで実行されているときにのみアクセスできます。ただし、 ケース。アプリが アプリがバックグラウンドで実行されているときのフォアグラウンド サービス、および 例外的なケースのいずれかを満たさない場合、システムは ForegroundServiceStartNotAllowedException

また、アプリがフォアグラウンド サービスを起動し、 使用中の権限(たとえば、ボディセンサー、カメラ、マイク、 ロケーション アプリがバックグラウンドで実行されているときは、サービスを作成できません。 アプリがバックグラウンド起動から除外された場合でも、 あります。その理由については、 使用中に必要なフォアグラウンド サービスを開始する 権限

バックグラウンド開始制限の除外

次の状況では、アプリがフォアグラウンド サービスまたは アプリがバックグラウンドで動作しているとき。

使用中の権限が必要なフォアグラウンド サービスの起動に関する制限

Android 14(API レベル 34)以降では、注意すべき特別な状況があります。 フォアグラウンド サービスを起動するときに、この間に権限を与える必要があります。

Android 14 以降をターゲットとするアプリの場合、オペレーティング システム チェックして、フォアグラウンド サービスの作成時に そのサービスタイプに適切な権限を付与できます。たとえば、Terraform で タイプのフォアグラウンド サービス microphone: オペレーティング アプリが現在動作しているバージョンと RECORD_AUDIO 付与します。その権限がない場合、システムは SecurityException

使用中の権限では、問題が発生する可能性があります。アプリに その権限が割り当てられているのは、使用中の権限のみ フォアグラウンドにする必要があります。つまり、アプリがバックグラウンドで動作していて、 フォアグラウンド サービスの場合、システムが アプリに必要な権限が現在付与されておらず、 SecurityException

同様に、アプリがバックグラウンドにあり、 BODY_SENSORS_BACKGROUND 権限を必要とするヘルスサービス、アプリ 現在その権限がなく、システムは例外をスローします。 (これは、異なる権限を必要とするヘルスサービス、 ACTIVITY_RECOGNITION など)。 PermissionChecker.checkSelfPermission() ではこの問題は防止できません。アプリに使用中の権限がある場合、かつ checkSelfPermission() を呼び出してその権限があるかどうかを確認し、メソッド アプリがバックグラウンドで実行されている場合でも PERMISSION_GRANTED を返します。Google メソッドが PERMISSION_GRANTED を返し、「アプリにこの権限がある」ことを示す 」というメッセージが表示されることがあります。

そのため、フォアグラウンド サービスが使用中の権限を必要とする場合は、 Context.startForegroundService() または Context.bindService() を呼び出す必要がある一方で、 アプリが可視アクティビティを持っていること。ただし、サービスが 定義された除外を使用します。

使用中権限の制限の免除

アプリの起動時にフォアグラウンド サービスが開始された場合であっても、 実行回数 バックグラウンドで、 アプリがフォアグラウンドで実行されているときのカメラ、マイクの情報 (「使用中のみ」)。

同じ状況で、サービスで フォアグラウンド サービスのタイプlocation であり、 がある ACCESS_BACKGROUND_LOCATION アクセスが許可されている場合でも、 アプリはバックグラウンドで動作します。

以下に、これらの状況を示します。

  • システム コンポーネントがサービスを開始します。
  • このサービスはまず、 ウィジェットをご覧ください。
  • このサービスはまず、通知を操作します。
  • このサービスはまず PendingIntent: 表示されます。
  • このサービスは、デバイス ポリシーであるアプリによって開始されます。 コントローラ: デバイス所有者モードで実行されます。
  • このサービスは、VoiceInteractionService を提供するアプリによって開始されます。
  • このサービスは、実行中のアプリによって START_ACTIVITIES_FROM_BACKGROUND 特権。
アプリで影響を受けるサービスを特定する

アプリをテストするとき、フォアグラウンド サービスを開始します。開始されたサービスが、位置情報、マイク、カメラに対するアクセスを制限されている場合は、次のメッセージが Logcat に表示されます。

Foreground service started from background can not have \
location/camera/microphone access: service SERVICE_NAME