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

Android 14, uygulamaların ön plan hizmetlerini ne zaman kullanmasına 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. uzaktaki 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 işlemi

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

  1. Job Scheduler ile ilk kez API bildiriyorsanız manifest dosyanızda JobService ve ilişkili izinleri açıklamalısınız. Ayrıca, veri aktarımınız için JobService somut bir 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 beyan edin:

    <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. Ayrıca yük boyutu tahmini sunmanız da önerilir. İşinizi oluştururken setEstimatedNetworkBytes() numaralı telefonu arayarak:

    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 devam ederken işi aktarım başlamadan önce planlayın Görünürse veya izin verilen koşullar listesindeyse:

    val jobScheduler: JobScheduler =
        context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
    jobScheduler.schedule(jobInfo)
    
  5. İş yürütülürken setNotification() JobService nesne algılandı. Bu değer, kullanıcının işin hem Görev Yöneticisi'nde hem de durum çubuğu bildiriminde çalışıyor alan:

    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 durumuyla ilgili bilgilendirmek için bildirimi düzenli olarak güncelleyin ve ilerlemeyi gösterir. Önceden aktarım boyutunu belirleyemiyorsanız veya tahmini aktarım boyutunu güncellemeniz gerekiyorsa updateEstimatedNetworkBytes() yeni API'yi kullanarak bilindikten sonra aktarım boyutunu güncelleyin.

  7. Yürütme tamamlandığında sisteme sinyal vermek için jobFinished() numaralı telefonu arayın ya da işin yeniden planlanması gerektiğini söylemeye gerek yoktur.

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ının görebildiğ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 kontroller sağlamanız önerilir.

Özel durumlarda, Görev Yöneticisi'nde işin yanında Durdur düğmesi görünmez veya iş, Görev Yöneticisi'nde hiç gösterilmez.

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 meydana gelirse 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ı belirler.
  • Sistemin, sistem sağlığına öncelik vermesi ve artan termal durum nedeniyle işleri durdurması gerekir.
  • Cihaz belleği yetersiz olduğundan uygulama işlemi sonlandırıldı.

İş, sistem tarafından durdurulduğunda (düşük bellek kapasiteli durum tarafından değil) sistem onStopJob() çağrısı yapar ve sistem, optimum olduğunu düşündüğü bir zamanda işi yeniden dener. Uygulamanızın, onStopJob() çağrılmasa bile 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şlerini planlamak 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 veri aktarımı işinin ne zaman planlanabileceğini belirlemek için sistem, uygulamaların özel durumlarda arka planda işlem başlatmasına izin veren koşul listesinin aynısını uygular. Bu koşul listesi, arka planda başlatılan ön plan hizmeti kısıtlamalarına yönelik muafiyetler grubuyla aynı olmaz.

Önceki ifadenin istisnaları şunlardır:

  • Bir uygulama arka planda işlem başlatabiliyorsa kullanıcı tarafından başlatılan veri aktarımı işlerini arka planda da başlatabilir.
  • Bir uygulamanın Son Kullanılanlar ekranındaki mevcut bir görevin arka yığınında bir etkinliği 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, en uygun 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 kullanılmaktadır.

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ı gösterilmektedir. Tabloyu bir iş kısıtlama yönteminin adına göre filtrelemek için tablonun önündeki 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 etme

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

  • İş kimliğini almak için, geliştirilmekte olan işin ardından tanımlanan değeri alın.
  • Bir işi hemen çalıştırmak veya durdurulan bir işi yeniden denemek için aşağıdaki komutu çalıştırın komutunu girin:

    adb shell cmd jobscheduler run -f APP_PACKAGE_NAME JOB_ID
    
  • Bir işi zorla durdurması için sistemi simüle etmek (sistem durumu veya (kota dışı koşullar) bir terminal penceresinde aşağıdaki komutu çalıştırın:

    adb shell cmd jobscheduler timeout TEST_APP_PACKAGE TEST_JOB_ID