Ön plan hizmetlerini kullanıcı tarafından başlatılan veri aktarımı işlerine taşıma

Android 14, uygulamaların ön plan hizmetlerini kullanmasına ne zaman izin verileceği konusunda katı kurallar uygular.

Ayrıca Android 14'te, bir işin kullanıcı tarafından başlatılan veri aktarımı işi olması gerektiğini belirten yeni bir API'yi kullanıma sunuyoruz. Bu API, kullanıcı tarafından başlatılan uzun süreli veri aktarımı (ör. uzak bir sunucudan dosya indirme) gerektiren kullanım alanları için faydalıdır. Bu tür görevler, kullanıcı tarafından başlatılan bir veri aktarımı işi kullanmalıdır.

Kullanıcı tarafından başlatılan veri aktarımı işleri kullanıcı tarafından başlatılır. Bu işler bildirim gerektirir, hemen başlar ve sistem koşulları izin verdiği ölçüde uzun bir süre boyunca çalıştırılabilir. Kullanıcı tarafından başlatılan birden fazla veri aktarımı işini eşzamanlı olarak çalıştırabilirsiniz.

Kullanıcı tarafından başlatılan işler, uygulama kullanıcı tarafından görünürken (veya izin verilen koşullardan birinde) planlanmalıdır. Kullanıcı tarafından başlatılan işler, tüm kısıtlamalar karşılandıktan sonra sistem durumu kısıtlamalarına tabi olarak işletim sistemi tarafından yürütülebilir. Sistem, işin ne kadar süre boyunca yürütüleceğini belirlemek için sağlanan tahmini yük boyutunu da kullanabilir.

Kullanıcı tarafından başlatılan veri aktarımı işleri için izin

Kullanıcı tarafından başlatılan veri aktarımı işlerinin çalışması için yeni bir izin gerekir: RUN_USER_INITIATED_JOBS. Sistem bu izni otomatik olarak verir. Uygulama manifestinizde izni beyan etmezseniz sistem bir SecurityException atar.

Kullanıcı tarafından başlatılan veri aktarımı işlerini planlama süreci

Kullanıcı tarafından başlatılan bir işi çalıştırmak için aşağıdakileri yapın:

  1. JobScheduler ile ilk kez API bildiriyorsanız manifest dosyanızda JobService öğesini ve ilişkili izinleri beyan edin. Ayrıca, veri aktarımınız için somut bir JobService alt sınıfı tanımlayın:

    <service android:name="com.example.app.CustomTransferService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:exported="false">
            ...
    </service>
    
    class CustomTransferService : JobService() {
      ...
    }
    
  2. Manifest'inizde RUN_USER_INITIATED_JOBS iznini bildirin:

    <manifest ...>
        <uses-permission android:name="android.permission.RUN_USER_INITIATED_JOBS" />
        <application ...>
            ...
        </application>
    </manifest>
    
  3. JobInfo nesnesi oluştururken yeni setUserInitiated() yöntemini çağırın. İşinizi oluştururken setEstimatedNetworkBytes() yöntemini çağırarak yük boyutu tahmini sunmanız da önerilir:

    val networkRequestBuilder = NetworkRequest.Builder()
            .addCapability(NET_CAPABILITY_INTERNET)
            .addCapability(NET_CAPABILITY_NOT_METERED)
            // Add or remove capabilities based on your requirements
            .build()
    
    val jobInfo = JobInfo.Builder()
            // ...
            .setUserInitiated(true)
            .setRequiredNetwork(networkRequestBuilder.build())
            .setEstimatedNetworkBytes(1024 * 1024 * 1024)
            // ...
            .build()
    
  4. Uygulama görünür durumdayken veya izin verilen koşullar listesindeyken işi aktarım başlamadan önce planlayın:

    val jobScheduler: JobScheduler =
        context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
    jobScheduler.schedule(jobInfo)
    
  5. İş yürütülürken JobService nesnesinde setNotification() işlevini çağırdığınızdan emin olun. Bu değer, kullanıcının hem Görev Yöneticisi'nde hem de durum çubuğundaki bildirim alanında işin çalışmakta olduğunu bilmesini sağlamak için kullanılır:

    class CustomTransferService : JobService() {
      override fun onStartJob(params: JobParameters?): Boolean {
          val notification = Notification.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
                  .setContentTitle("My user-initiated data transfer job")
                  .setSmallIcon(android.R.mipmap.myicon)
                  .setContentText("Job is running")
                  .build()
    
          setNotification(params, notification.id, notification,
                  JobService.JOB_END_NOTIFICATION_POLICY_DETACH)
          // Do the job execution.
      }
    }
    
  6. Kullanıcıyı işin durumu ve ilerlemesi konusunda bilgilendirmek için bildirimi düzenli olarak güncelleyin. Aktarım boyutunu işi planlamadan önce belirleyemiyorsanız veya tahmini aktarım boyutunu güncellemeniz gerekiyorsa aktarım boyutunu öğrenildikten sonra güncellemek için yeni API'yi (updateEstimatedNetworkBytes()) kullanın.

  7. Yürütme tamamlandığında, işin tamamlandığını veya işin yeniden planlanması gerektiğini sisteme bildirmek için jobFinished() işlevini çağırın.

Kullanıcı tarafından başlatılan veri aktarımı işleri durdurulabilir

Hem kullanıcı hem de sistem, kullanıcı tarafından başlatılan aktarım işlerini durdurabilir.

Kullanıcı tarafından, Görev Yöneticisi'nden

Kullanıcı, Görev Yöneticisi'nde görünen, kullanıcı tarafından başlatılan bir veri aktarımı işini durdurabilir.

Kullanıcı Durdur'a bastığı anda sistem aşağıdakileri yapar:

  • Çalışan diğer tüm işler veya ön plan hizmetleri de dahil olmak üzere uygulamanızın sürecini hemen sonlandırır.
  • Çalışan hiçbir iş için onStopJob() işlevini çağırmaz.
  • Kullanıcıların görebileceği işlerin yeniden planlanmasını önler.

Bu nedenlerle, işin sorunsuz bir şekilde durdurulmasına ve yeniden planlanmasına olanak tanımak için iş için gönderilen bildirimde kontrollerin sağlanması önerilir.

Özel durumlarda, Görev Yöneticisi'nde işin yanında Durdur düğmesinin görünmediğini veya işin Görev Yöneticisi'nde hiç görünmediğini unutmayın.

Sistem tarafından

Normal işlerin aksine, kullanıcı tarafından başlatılan veri aktarımı işleri Uygulama Bekleme Paketleri kotalarından etkilenmez. Ancak aşağıdaki koşullardan herhangi biri gerçekleştiğinde sistem işi yine de durdurur:

  • Geliştirici tarafından tanımlanan bir kısıtlama artık karşılanmıyor.
  • Sistem, işin veri aktarımı görevini tamamlamak için gerekenden daha uzun süre çalıştığını tespit eder.
  • Sistemin, sistem sağlığına öncelik vermesi ve artan ısı durumu nedeniyle işleri durdurması gerekir.
  • Cihaz belleği yetersiz olduğundan uygulama işlemi sonlandırıldı.

İş, sistem tarafından durdurulduğunda (düşük bellekli durum tarafından değil) sistem onStopJob() çağırır ve sistem, sistemin optimum olduğunu belirlediği bir zamanda işi yeniden dener. onStopJob() çağrılmasa bile uygulamanızın veri aktarımı durumunu koruyabildiğinden ve onStartJob() tekrar çağrıldığında uygulamanızın bu durumu geri yükleyebileceğinden emin olun.

Kullanıcı tarafından başlatılan veri aktarımı işlerinin planlanması için izin verilen koşullar

Uygulamalar yalnızca görünür penceredeyse veya belirli koşullar karşılanıyorsa kullanıcı tarafından başlatılan veri aktarımı işi başlatabilir. Kullanıcı tarafından başlatılan bir veri aktarımı işinin ne zaman planlanabileceğini belirlemek için sistem, uygulamaların özel durumlarda arka plandan etkinlik başlatmasına izin veren aynı koşul listesini uygular. Bu koşul listesi, arka planda başlatılan ön plan hizmeti kısıtlamalarıyla ilgili muafiyet grubuyla aynı değildir.

Önceki ifadenin istisnaları şunlardır:

  • Bir uygulama arka planda etkinlik başlatabiliyorsa kullanıcı tarafından başlatılan veri aktarımı işlerini de arka planda başlatabilir.
  • Bir uygulamanın Son Kullanılanlar ekranındaki mevcut bir görevin arka yığınında bir etkinlik varsa bu etkinlik tek başına kullanıcı tarafından başlatılan bir veri aktarım işinin çalıştırılmasına izin vermez.

İş, izin verilen koşullar listesinde yer almayan başka bir zamana planlandıysa iş başarısız olur ve RESULT_FAILURE hata kodu döndürür.

Kullanıcı tarafından başlatılan veri aktarımı işleri için izin verilen kısıtlamalar

Android, optimum noktalarda çalışan işleri desteklemek için her iş türüne kısıtlama atama özelliği sunar. Bu kısıtlamalar Android 13'te zaten mevcuttur.

Not: Aşağıdaki tabloda yalnızca her iş türü arasında farklılık gösteren kısıtlamalar karşılaştırılmaktadır. Tüm kısıtlamalar için JobScheduler geliştirici sayfasına veya iş kısıtlamalarına bakın.

Aşağıdaki tabloda, belirli bir iş kısıtlamasını destekleyen farklı iş türleri ve WorkManager'ın desteklediği iş kısıtlamaları grubu gösterilmektedir. Tabloyu bir iş kısıtlama yönteminin adına göre filtrelemek için tablodan önce gelen arama çubuğunu kullanın.

Kullanıcı tarafından başlatılan veri aktarımı işlerinde izin verilen kısıtlamalar şunlardır:

  • setBackoffCriteria(JobInfo.BACKOFF_POLICY_EXPONENTIAL)
  • setClipData()
  • setEstimatedNetworkBytes()
  • setMinimumNetworkChunkBytes()
  • setPersisted()
  • setNamespace()
  • setRequiredNetwork()
  • setRequiredNetworkType()
  • setRequiresBatteryNotLow()
  • setRequiresCharging()
  • setRequiresStorageNotLow()

Test

Aşağıdaki listede, uygulamanızın işlerini manuel olarak test etmeyle ilgili bazı adımlar gösterilmektedir:

  • İş kimliğini almak için, oluşturulan işin başında tanımlanan değeri alın.
  • Bir işi hemen çalıştırmak veya durdurulan bir işi yeniden denemek için bir terminal penceresinde aşağıdaki komutu çalıştırın:

    adb shell cmd jobscheduler run -f APP_PACKAGE_NAME JOB_ID
    
  • Sistemin durumu veya kota dışı koşullar nedeniyle bir işi zorla durdurduğunu simüle etmek için bir terminal penceresinde aşağıdaki komutu çalıştırın:

    adb shell cmd jobscheduler timeout TEST_APP_PACKAGE TEST_JOB_ID