Ön plan hizmeti başlatma

Uygulamanızdan ön plan hizmeti başlatmak için iki adım vardır. Öncelikle, context.startForegroundService() işlevini çağırarak hizmeti başlatmanız gerekir. Ardından, hizmetin kendisini ön plan hizmetine yükseltmek için ServiceCompat.startForeground() hizmetini çağırmasını sağlayın.

Ön koşullar

Uygulamanızın hedeflediği API düzeyine bağlı olarak, bir uygulamanın ön plan hizmetini ne zaman başlatabileceği konusunda bazı kısıtlamalar vardır.

  • Android 12 (API düzeyi 31) veya sonraki sürümleri hedefleyen uygulamaların, uygulama arka plandayken belirli birkaç istisna dışında ön plan hizmeti başlatmasına izin verilmez. Daha fazla bilgi ve bu kuralın istisnaları hakkında bilgi edinmek için Arka plandan ön plan hizmeti başlatmayla ilgili kısıtlamalar başlıklı makaleyi inceleyin.

  • Android 14'ü (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar, ön plan hizmeti türü için uygun izinleri istemelidir. Uygulama bir hizmeti ön plana çıkarmaya çalıştığında sistem, uygun izinleri kontrol eder ve uygulama izinlerden herhangi birini kullanmıyorsa SecurityException istisnası oluşturur. Örneğin, location türünde bir ön plan hizmeti başlatmaya çalışırsanız sistem, uygulamanızın ACCESS_COARSE_LOCATION veya ACCESS_FINE_LOCATION iznine sahip olup olmadığını kontrol eder. Ön plan hizmeti türü dokümanında, her ön plan hizmeti türü için gerekli ön koşullar listelenir.

Hizmet başlatma

Ön plan hizmetini başlatmak için önce normal (ön plan olmayan) bir hizmet olarak başlatmanız gerekir:

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);

Kodla ilgili önemli noktalar

  • Kod snippet'i bir hizmeti başlatıyor. Ancak hizmet henüz ön planda çalışmıyor. Hizmetin kendisinde, hizmeti ön plan hizmetine yükseltmek için ServiceCompat.startForeground() işlevini çağırmanız gerekir.

Bir hizmeti ön plana çıkarma

Bir hizmet çalışmaya başladıktan sonra, hizmetin ön planda çalışmasını istemek için ServiceCompat.startForeground()'ı çağırmanız gerekir. Normalde bu yöntemi hizmetin onStartCommand() yönteminde çağırırsınız.

ServiceCompat.startForeground() aşağıdaki parametreleri alır:

Kullanım alanına bağlı olarak startForeground() manifest dosyasında tanımlanan türler bölümüne ilettiğiniz ön plan hizmeti türleri. Daha sonra, başka hizmet türleri eklemeniz gerekirse startForeground() numaralı telefonu tekrar arayabilirsiniz.

Örneğin, bir fitness uygulamasının her zaman location bilgisine ihtiyaç duyan ancak medya oynatması gerekebilen veya gerekmeyen bir koşu takipçisi hizmeti çalıştırdığını varsayalım. Manifestte hem location hem de mediaPlayback değerlerini belirtmeniz gerekir. Bir kullanıcı koşuya başladığında yalnızca konumunun izlenmesini istiyorsa uygulamanız startForeground() işlevini çağırmalı ve yalnızca ACCESS_FINE_LOCATION iznini geçirmelidir. Ardından, kullanıcı ses çalmaya başlamak isterse startForeground() işlevini tekrar çağırın ve tüm ön plan hizmeti türlerinin bit düzeyinde kombinasyonunu (bu örnekte ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK) iletin.

Aşağıdaki örnekte, bir kamera hizmetinin kendisini ön plan hizmeti olarak tanıtmak için kullanacağı kod gösterilmektedir:

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)
            }
            // ...
        }
    }

    //...
}

Kodla ilgili önemli noktalar

  • Uygulama, manifest dosyasında CAMERA iznine ihtiyacı olduğunu zaten belirtmiş olmalıdır. Ancak uygulamanın, kullanıcının bu izni verdiğinden emin olmak için çalışma zamanında da kontrol etmesi gerekir. Uygulama, doğru izinlere sahip değilse kullanıcıyı bu sorun hakkında bilgilendirmelidir.
  • Android platformunun farklı sürümlerinde farklı ön plan hizmeti türleri kullanıma sunuldu. Bu kod, üzerinde çalıştığı Android sürümünü kontrol eder ve uygun izinleri ister.
  • Kod, izin verilmeyen bir durumda ön plan hizmeti başlatmaya çalışması ihtimaline karşı ForegroundServiceStartNotAllowedException kontrolü yapar (örneğin, uygulama arka plandayken hizmeti ön plana getirmeye çalışıyorsa).