Ön plan hizmetleri, kullanıcının fark edebileceği işlemleri gerçekleştirir.
Ön plan hizmetleri, uygulamanızın ön planda bir işlem gerçekleştirdiğini ve sistem kaynaklarını kullandığını bildirmek için bir durum çubuğu bildirimi gösterir.
Ön plan hizmetlerini kullanan uygulamalara örnek olarak şunlar verilebilir:
- Ön plan hizmetinde müzik çalan bir müzik çalma uygulaması. Bildirimde, çalmakta olan şarkı gösterilebilir.
- Kullanıcıdan izin aldıktan sonra kullanıcının koşusunu ön plan hizmetinde kaydeden bir fitness uygulaması. Bildirimde, kullanıcının mevcut fitness oturumu sırasında katettiği mesafe gösterilebilir.
Ön plan hizmetini yalnızca uygulamanızın kullanıcı tarafından fark edilebilir bir görevi gerçekleştirmesi gerektiğinde (kullanıcıyla doğrudan etkileşimde bulunmasa bile) kullanın. İşlem, minimum öncelikli bildirim kullanmak istemenize neden olacak kadar önemli değilse bunun yerine bir arka plan görevi oluşturun.
Bu dokümanda, ön plan hizmetlerini kullanmak için gereken izinler ve bir ön plan hizmetinin nasıl başlatılıp arka plandan kaldırılacağı açıklanmaktadır. Ayrıca belirli kullanım alanlarının ön plan hizmeti türleriyle nasıl ilişkilendirileceği ve arka planda çalışan bir uygulamadan ön plan hizmeti başlattığınızda geçerli olan erişim kısıtlamaları açıklanmaktadır.
Kullanıcı varsayılan olarak bildirimi kapatabilir
Android 13'ten (API düzeyi 33) itibaren, kullanıcılar bir ön plan hizmetiyle ilişkilendirilmiş bildirimi varsayılan olarak kapatabilir. Kullanıcılar bunun için bildirimde bir kaydırma hareketi gerçekleştirir. Genellikle, ön plan hizmeti durdurulmadığı veya ön plandan kaldırılmadığı sürece bildirim kapatılmaz.
Bildirimin kullanıcı tarafından kapatılmamasını istiyorsanız Notification.Builder
kullanarak bildiriminizi oluştururken true
öğesini setOngoing()
yöntemine iletin.
Hemen bildirim gösteren hizmetler
Bir ön plan hizmetinde aşağıdaki özelliklerden en az biri varsa sistem, Android 12 veya sonraki sürümleri çalıştıran cihazlarda bile hizmet başladıktan hemen sonra ilgili bildirimi gösterir:
- Hizmet, işlem düğmeleri içeren bir bildirimle ilişkilendirilir.
- Hizmetin
foregroundServiceType
simgesimediaPlayback
,mediaProjection
veyaphoneCall
şeklindedir. - Hizmet; bildirimin kategori özelliğinde tanımlandığı gibi telefon aramaları, gezinme veya medya oynatma ile ilgili bir kullanım alanı sağlar.
- Hizmet, bildirimi ayarlarken
FOREGROUND_SERVICE_IMMEDIATE
öğesinisetForegroundServiceBehavior()
'e ileterek davranış değişikliğini devre dışı bıraktı.
Android 13 (API düzeyi 33) veya sonraki sürümlerde kullanıcı bildirim iznini reddederse Görev Yöneticisi'nde ön plan hizmetleriyle ilgili bildirimleri görmeye devam ederler ancak bildirim çekmecesinde görmezler.
Manifest'inizde ön plan hizmetlerini bildirme
Uygulamanızın manifest dosyasında uygulamanızın her ön plan hizmetini bir <service>
öğesiyle tanımlayın. Her hizmet için ne tür bir iş yaptığını açıklamak amacıyla bir android:foregroundServiceType
özelliği kullanın.
Örneğin, uygulamanız müzik çalan bir ön plan hizmeti oluşturuyorsa hizmeti şu şekilde beyan edebilirsiniz:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</manifest>
Hizmetiniz için geçerli olan birden fazla tür varsa bunları |
operatörüyle ayırın. Örneğin, kamera ve mikrofonu kullanan bir hizmet bunu şöyle bildirir:
android:foregroundServiceType="camera|microphone"
Ön plan hizmeti izinlerini isteme
Android 9 (API düzeyi 28) veya sonraki sürümleri hedefleyen ve ön plan hizmetlerini kullanan uygulamaların, aşağıdaki kod snippet'inde gösterildiği gibi uygulama manifest dosyasında FOREGROUND_SERVICE
isteğinde bulunması gerekir. Bu normal bir izin olduğu için sistem, izni istekte bulunan uygulamaya otomatik olarak verir.
Ayrıca, uygulama API düzeyi 34 veya üstünü hedefliyorsa ön plan hizmetinin yapacağı iş için uygun izin türünü istemelidir. Her ön plan hizmet türünün ilgili bir izin türü vardır. Örneğin, bir uygulama kamerayı kullanan bir ön plan hizmetini başlatırsa hem FOREGROUND_SERVICE
hem de FOREGROUND_SERVICE_CAMERA
izinlerini istemeniz gerekir. Bunların tümü normal izinler olduğu için manifest dosyasında listelenmeleri durumunda sistem bunları otomatik olarak verir.
<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>
Ön plan hizmeti ön koşulları
Android 14'ten (API düzeyi 34) itibaren, bir ön plan hizmetini başlattığınızda sistem hizmet türüne göre belirli ön koşulları kontrol eder. Örneğin, location
türünde bir ön plan hizmeti başlatmaya çalışırsanız sistem, uygulamanızın zaten ACCESS_COARSE_LOCATION
veya ACCESS_FINE_LOCATION
iznine sahip olduğundan emin olmak için kontrol eder. Aksi halde sistem SecurityException
mesajını döndürür.
Bu nedenle, bir ön plan hizmetini başlatmadan önce gerekli ön koşulların karşılandığını onaylamanız gerekir. Ön plan hizmet türü belgelerinde, her ön plan hizmet türü için gerekli ön koşullar listelenmektedir.
Ön plan hizmeti başlatma
Sistemin bir hizmeti ön plan hizmeti olarak çalıştırmasını istemeden önce hizmetin kendisini başlatın:
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);
Hizmetin içinde (genellikle onStartCommand()
konumunda) hizmetinizin ön planda çalışmasını isteyebilirsiniz. Bunu yapmak için ServiceCompat.startForeground()
numaralı telefonu arayın (androidx-core 1.12 ve sonraki sürümlerde kullanılabilir). Bu yöntem aşağıdaki parametreleri alır:
- Hizmet
- Durum çubuğunda bildirimi benzersiz şekilde tanımlayan pozitif bir tam sayı
Notification
nesnesinin kendisi- Hizmet tarafından yapılan işleri tanımlayan ön plan hizmeti türleri
Bu türler, belirli kullanım alanına bağlı olarak manifest'te belirtilen türlerin bir alt kümesi olabilir. Ardından, daha fazla hizmet türü eklemeniz gerekirse startForeground()
yöntemini tekrar çağırabilirsiniz.
Örneğin, bir fitness uygulamasının, her zaman location
bilgisine ihtiyacı olan, ancak medya oynatması gereken veya olmayan bir koşu takip hizmeti çalıştırdığını varsayalım. Manifest'te hem location
hem de mediaPlayback
öğesini beyan etmeniz gerekir. Bir kullanıcı koşu başlatırsa ve yalnızca konumunun izlenmesini isterse uygulamanız startForeground()
yöntemini çağırmalı ve yalnızca ACCESS_FINE_LOCATION
iznini iletmelidir. Ardından, kullanıcı ses çalmaya başlamak isterse startForeground()
yöntemini tekrar çağırın ve tüm ön plan hizmet türlerinin bit tabanlı kombinasyonunu (bu örnekte ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
) iletin.
Burada, kamera ön plan hizmetini başlatan bir örnek verilmiştir:
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 = 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 { 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) } // ... } } //... }
Bir hizmeti ön plandan kaldırma
Hizmeti ön plandan kaldırmak için stopForeground()
numaralı telefonu arayın.
Bu yöntemde, durum çubuğu bildiriminin kaldırılıp kaldırılmayacağını belirten bir boole kullanılır. Hizmetin çalışmaya devam ettiğini unutmayın.
Ön planda çalışırken hizmeti durdurursanız hizmetin bildirimi kaldırılır.
Ön plan hizmetleri çalıştıran uygulamaların kullanıcı tarafından durdurulmasını ele alma
Android 13'ten (API düzeyi 33) itibaren, kullanıcılar devam eden ön plan hizmetleri olan bir uygulamayı durdurmak için uygulamanın hedef SDK sürümünden bağımsız olarak, bildirim çekmecesinden bir iş akışını tamamlayabilirler. Görev Yöneticisi adı verilen bu olanak, şu anda bir ön plan hizmetini çalıştırmakta olan uygulamaların listesini gösterir.
Bu liste Etkin uygulamalar olarak etiketlenir. Her uygulamanın yanında bir Durdur düğmesi bulunur. Şekil 1'de Android 13 çalıştıran bir cihazdaki Görev Yöneticisi iş akışı gösterilmektedir.
Kullanıcı, Görev Yöneticisi'nde uygulamanızın yanındaki Durdur düğmesine bastığında aşağıdaki işlemler gerçekleşir:
- Sistem, uygulamanızı bellekten kaldırır. Dolayısıyla, yalnızca ön plan hizmeti değil, uygulamanızın tamamı durur.
- Sistem, uygulamanızın etkinlik geri yığınını kaldırır.
- Medya oynatma işlemi durur.
- Ön plan hizmetiyle ilişkili bildirim kaldırılır.
- Uygulamanız geçmişte kalır.
- Planlanmış görevler, planlanan zamanda yürütülür.
- Alarmlar programlanan zamanda veya zaman aralığında çalar.
Kullanıcı uygulamanızı durdurduğunda ve durdurduktan sonra uygulamanızın beklendiği gibi davranıp davranmadığını test etmek için bir terminal penceresinde aşağıdaki ADB komutunu çalıştırın:
adb shell cmd activity stop-app PACKAGE_NAME
Muafiyetler
Sistem, belirli uygulama türleri için çeşitli muafiyet düzeyleri sağlar. Bunlar, aşağıdaki bölümlerde açıklanmıştır.
Muafiyetler işlem başına değil, uygulama başına yapılır. Sistem, bir uygulamadaki bir işlemi muaf tutarsa bu uygulamadaki diğer tüm işlemler de muaf olur.
Görev Yöneticisi'nde görüntülenmeyecek muaf tutmalar
Aşağıdaki uygulamalar bir ön plan hizmetini çalıştırabilir ve Görev Yöneticisi'nde hiç görünmeyebilir:
- Sistem düzeyindeki uygulamalar
- Güvenlik uygulamaları (
ROLE_EMERGENCY
rolüne sahip uygulamalar) - Demo modundaki cihazlar
Kullanıcıların durdurulabilirliğinden muaf tutma
Aşağıdaki türlerde uygulamalar ön plan hizmeti çalıştırdığında, bu uygulamalar Görev Yöneticisi'nde görünür, ancak kullanıcının dokunması için uygulama adının yanında Durdur düğmesi yoktur:
- Cihaz sahibi uygulamaları
- Profil sahibi uygulamaları
- Kalıcı uygulamalar
ROLE_DIALER
rolüne sahip uygulamalar
Ön plan hizmetleri yerine amaca yönelik API'ler kullanın
Çoğu kullanım alanında, ön plan hizmetini kullanmak için kullanabileceğiniz platform veya Jetpack API'leri mevcuttur. Amaca yönelik uygun bir API varsa bir ön plan hizmeti yerine neredeyse her zaman onu kullanmalısınız. Amaca özel API'ler genellikle, normalde kendi başınıza oluşturmanız gereken kullanım alanına özel ek yetenekler sağlar. Örneğin Bubbles API, sohbet balonu özelliklerini uygulaması gereken mesajlaşma uygulamalarına yönelik karmaşık kullanıcı arayüzü mantığını işler.
Ön plan hizmet türleri belgelerinde, ön plan hizmetleri yerine kullanılabilecek iyi alternatifler listelenmiştir.
Arka plandan ön plan hizmeti başlatmayla ilgili kısıtlamalar
Android 12 veya sonraki sürümleri hedefleyen uygulamalar, birkaç özel durum dışında arka planda çalışırken ön plan hizmetlerini başlatamaz. Bir uygulama, arka planda çalışırken bir ön plan hizmeti başlatmaya çalışırsa ve ön plan hizmeti istisnai durumlardan birini karşılayamazsa sistem bir ForegroundServiceStartNotAllowedException
gönderir.
Ayrıca bir uygulama, kullanım sırasında izinlerine (örneğin, vücut sensörü, kamera, mikrofon veya konum izinleri) ihtiyaç duyan bir ön plan hizmetini başlatmak istiyorsa uygulama arka planda başlatma kısıtlamalarının muafiyetlerinden birine dahil olsa bile, hizmeti oluşturamaz. Bunun nedeni, Kullanım sırasında izin verilmesi gereken ön plan hizmetlerini başlatmayla ilgili kısıtlamalar bölümünde açıklanmıştır.
Arka planda başlatma kısıtlamalarından muaf tutma
Aşağıdaki durumlarda uygulamanız arka planda çalışırken bile ön plan hizmetlerini başlatabilir:
- Uygulamanız, etkinlik gibi kullanıcı tarafından görülebilen bir durumdan geçirilir.
- Mevcut bir görevin arka yığınında bir etkinliğin bulunduğu durumlar haricinde, uygulamanız arka planda bir etkinlik başlatabilir.
Uygulamanız, Firebase Cloud Messaging'i kullanarak yüksek öncelikli bir mesaj alıyor.
Kullanıcı, uygulamanızla ilgili bir kullanıcı arayüzü öğesinde işlem gerçekleştirir. Örneğin, bir balon, bildirim, widget veya etkinlikle etkileşimde bulunabilir.
Uygulamanız, kullanıcının istediği bir işlemi tamamlamak için tam alarm çağırır.
Uygulamanız, cihazın mevcut giriş yöntemidir.
Uygulamanız, coğrafi sınırlama veya etkinlik tanıma geçişi ile ilgili bir etkinlik aldığında.
Cihaz yeniden başlatılıp
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
veya yayın alıcıdaACTION_MY_PACKAGE_REPLACED
amaç işlemini aldıktan sonra.Uygulamanız
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
veyaACTION_LOCALE_CHANGED
niyet eylemini bir yayın alıcısında alır.Uygulamanız,
NfcService
kaynağındanACTION_TRANSACTION_DETECTED
etkinliğini alır.Cihaz sahipleri ve profil sahipleri gibi belirli sistem rollerine veya izinlere sahip uygulamalar.
Uygulamanız Companion Device Manager'ı kullanıyor ve
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
iznini veyaREQUEST_COMPANION_RUN_IN_BACKGROUND
iznini beyan ediyor. Mümkün olduğundaREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
kullanın.Uygulamanız
SYSTEM_ALERT_WINDOW
iznine sahip.Kullanıcı, uygulamanız için pil optimizasyonlarını kapatır.
Kullanım sırasında izin gerektiren ön plan hizmetlerinin başlatılmasıyla ilgili kısıtlamalar
Android 14 (API düzeyi 34) veya sonraki sürümlerde, kullanım sırasında izin gerektiren bir ön plan hizmeti başlatırken dikkat etmeniz gereken özel durumlar vardır.
Uygulamanız Android 14 veya sonraki bir sürümü hedefliyorsa işletim sistemi, bir ön plan hizmeti oluşturduğunuzda uygulamanızın bu hizmet türü için uygun tüm izinlere sahip olduğundan emin olmak amacıyla kontrol eder. Örneğin, mikrofon türünde bir ön plan hizmeti oluşturduğunuzda işletim sistemi uygulamanızın şu anda RECORD_AUDIO
iznine sahip olduğunu doğrular. Bu izne sahip değilseniz sistem bir SecurityException
gönderir.
Kullanımdaki izinler için bu durum potansiyel bir soruna neden olur. Uygulamanızın kullanım sırasında izni varsa bu izni yalnızca ön plandayken alabilir. Diğer bir deyişle, uygulamanız arka plandaysa ve kamera, konum veya mikrofon türünde bir ön plan hizmeti oluşturmaya çalışırsa sistem, uygulamanızın şu anda gerekli izinlere sahip olmadığını tespit eder ve bir SecurityException
gönderir.
Benzer şekilde, uygulamanız arka planda çalışıyorsa ve BODY_SENSORS_BACKGROUND
iznini gerektiren bir sağlık hizmeti oluşturuyorsa uygulama şu anda bu izne sahip değildir ve sistem bir istisna uygular.
(ACTIVITY_RECOGNITION
gibi farklı izinlere ihtiyacı olan bir sağlık hizmeti söz konusuysa bu durum geçerli değildir.) ContextCompat.checkSelfPermission()
yöntemini çağırmak bu sorunu önlemez. Uygulamanızın kullanım sırasında izni varsa ve bu izne sahip olup olmadığını kontrol etmek için checkSelfPermission()
yöntemini çağırırsa yöntem, uygulama arka planda olsa bile PERMISSION_GRANTED
değerini döndürür. Yöntem PERMISSION_GRANTED
değerini döndürdüğünde, "uygulama kullanımdayken uygulamanız bu izne sahip olur" ifadesini içerir.
Bu nedenle, ön plan hizmetiniz kullanım sırasında izne ihtiyaç duyuyorsa hizmet tanımlanmış muafiyetlerden birine girmiyorsa uygulamanızın görünür bir etkinliği varken Context.startForegroundService()
veya Context.bindService()
çağırmanız gerekir.
Kullanımdaki izinlerle ilgili kısıtlamalardan muaf tutma
Bazı durumlarda, bir ön plan hizmeti arka planda çalışırken başlatılsa bile, uygulama ön planda çalışırken ("kullanımdayken") konum, kamera ve mikrofon bilgilerine erişmeye devam edebilir.
Aynı durumlarda, hizmet ön plan hizmeti türünü location
olarak beyan ederse ve ACCESS_BACKGROUND_LOCATION
iznine sahip bir uygulama tarafından başlatılırsa bu hizmet, uygulama arka planda çalışsa bile konum bilgilerine her zaman erişebilir.
Aşağıdaki listede şu durumlar yer almaktadır:
- Bir sistem bileşeni hizmeti başlatır.
- Hizmet, uygulama widget'larıyla etkileşimde bulunarak başlar.
- Hizmet, bir bildirimle etkileşimde bulunarak başlar.
- Hizmet, farklı ve görünür bir uygulamadan gönderilen
PendingIntent
ile başlar. - Hizmet, cihaz sahibi modunda çalışan bir cihaz politikası denetleyici uygulama tarafından başlatılır.
- Hizmet,
VoiceInteractionService
bilgisini sağlayan bir uygulama tarafından başlatılır. - Hizmet,
START_ACTIVITIES_FROM_BACKGROUND
ayrıcalıklı izne sahip bir uygulama tarafından başlatılır.
Uygulamanızda hangi hizmetlerin etkilendiğini belirleme
Uygulamanızı test ederken ön plan hizmetlerini başlatın. Başlatılan bir hizmet konum, mikrofon ve kameraya erişimi kısıtladıysa Logcat'te aşağıdaki mesaj görünür:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME