Ön plan hizmeti başlatma

Uygulamanızdan ön plan hizmeti başlatmak için iki adım vardır. Öncelikle context.startForegroundService() çağrısını yaparak hizmeti başlatmanız gerekir. Ardından, hizmetin kendisini ön plan hizmetine yükseltmek için ServiceCompat.startForeground() çağrısı yapması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 ön plan hizmeti başlatmasına belirli istisnalar dışında izin verilmez. Daha fazla bilgi ve bu kuralın istisnaları hakkında bilgi 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 uygulamada eksik izin varsa SecurityException hatası verir. Örneğin, location türündeki bir ön plan hizmetini 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 hizmet türü dokümanlarında, her ön plan hizmet türü için gerekli ön koşullar listelenir.

Hizmet yayınlama

Bir ön plan hizmetini başlatmak için önce bunu sıradan (ön planda 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ır. Ancak hizmet henüz ön planda çalışmıyor. Hizmetin içinde, hizmeti ön plan hizmetine tanıtmak için ServiceCompat.startForeground() işlevini çağırmanız gerekir.

Bir hizmeti ön plana taşıma

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

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

Belirli kullanım alanına bağlı olarak startForeground() manifest'de beyan edilen türlere ilettiğiniz ön plan hizmet türleri. Ardından, daha fazla hizmet türü eklemeniz gerekirse startForeground() numaralı telefonu tekrar arayabilirsiniz.

Örneğin, bir fitness uygulamasının her zaman location bilgilerine ihtiyaç duyan ancak medya oynatması gerekmeyen veya gerekmeyen bir koşu takip hizmeti çalıştırdığını varsayalım. Manifestte hem location hem de mediaPlayback öğelerini belirtmeniz gerekir. Bir kullanıcı koşuya başlar ve yalnızca konumunun izlenmesini isterse uygulamanız startForeground() işlevini çağırmalı ve yalnızca ACCESS_FINE_LOCATION iznini iletmelidir. 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 kombinasyonunu (bu durumda ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK) iletin.

Aşağıdaki örnekte, bir kamera hizmetinin kendisini ön plan hizmetine 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 ihtiyaç duyduğunu beyan etmiş. Ancak uygulamanın, kullanıcının bu izni verdiğinden emin olmak için çalışma zamanında da kontrol yapması gerekir. Uygulamanın gerekli izinlere sahip olmadığı durumlarda kullanıcıya sorun hakkında bilgi vermesi gerekir.
  • Android platformunun farklı sürümleriyle birlikte farklı ön plan hizmet türleri kullanıma sunuldu. Bu kod, hangi Android sürümünün çalıştığını kontrol eder ve uygun izinleri ister.
  • Kod, izin verilmeyen bir durumda ön plan hizmeti başlatmaya çalışıyorsa (örneğin, uygulama arka plandayken hizmeti ön plana taşımaya çalışıyorsa) ForegroundServiceStartNotAllowedException değerini kontrol eder.