Pada peluncuran aplikasi, aplikasi memulai layanan yang harus melakukan beberapa tugas jaringan. Setelah menargetkan API level 26, aplikasi saya gagal memulai layanan di Android 8.0 di latar belakang.
Disebabkan oleh: java.lang.IllegalStateException: Tidak diizinkan untuk memulai layanan Intent {cmp = my.app.tt / com.my.service}: aplikasi berada di latar belakang UidRecord {90372b1 u0a136 Projek siaga CEM: 1 seq (0,0 , 0)}
seperti yang saya pahami terkait dengan: Batas eksekusi latar belakang
Metode startService () sekarang melempar IllegalStateException jika aplikasi yang menargetkan Android 8.0 mencoba menggunakan metode itu dalam situasi ketika tidak diizinkan untuk membuat layanan latar belakang.
" dalam situasi ketika itu tidak diizinkan " - apa artinya sebenarnya ?? Dan bagaimana cara memperbaikinya. Saya tidak ingin mengatur layanan saya sebagai "foreground"
startForegroundService()
sebagai gantistartService()
.Jawaban:
Situasi yang diizinkan adalah daftar putih sementara di mana layanan latar belakang berperilaku sama seperti sebelum Android O.
Sumber: https://developer.android.com/about/versions/oreo/background.html
Jadi dengan kata lain jika layanan latar belakang Anda tidak memenuhi persyaratan daftar putih Anda harus menggunakan JobScheduler baru . Ini pada dasarnya sama dengan layanan latar belakang, tetapi dipanggil secara berkala alih-alih berjalan di latar belakang terus menerus.
Jika Anda menggunakan IntentService, Anda dapat mengubah ke JobIntentService. Lihat jawaban @ kosev di bawah ini .
sumber
FirebaseInstanceIdService
danonTokenRefresh
metodenya pesan FCM prioritas tinggi?Saya mendapat solusi. Untuk perangkat pra-8.0, Anda hanya perlu menggunakan
startService()
, tetapi untuk perangkat pasca-7.0, Anda harus menggunakanstartForgroundService()
. Berikut ini contoh kode untuk memulai layanan.Dan di kelas layanan, silakan tambahkan kode di bawah ini untuk pemberitahuan:
Di mana O adalah Android versi 26.
sumber
ContextCompat.startForegroundService(...)
lib dukungan yang dapat digunakan sebagai gantinya.Cara terbaik adalah dengan menggunakan JobIntentService yang menggunakan JobScheduler baru untuk Oreo atau layanan lama jika tidak tersedia.
Nyatakan dalam manifes Anda:
Dan dalam layanan Anda, Anda harus mengganti onHandleIntent dengan onHandleWork:
Kemudian Anda memulai layanan Anda dengan:
sumber
enqueueWork(...)
adalah metode statis juga.Jika layanan ini berjalan di utas latar belakang dengan memperluas
IntentService
, Anda dapat menggantiIntentService
denganJobIntentService
yang disediakan sebagai bagian dari Perpustakaan Dukungan AndroidKeuntungan menggunakan
JobIntentService
adalah, berperilaku sebagai perangkatIntentService
pra-O dan pada O dan lebih tinggi, mengirimkannya sebagai pekerjaanJobScheduler
juga dapat digunakan untuk pekerjaan yang diminta secara berkala / sesuai permintaan. Tetapi, pastikan untuk menangani kompatibilitas mundur karenaJobScheduler
API hanya tersedia dari API 21sumber
Di Oreo, Android membatasi batas layanan latar belakang .
Namun jika Anda selalu perlu menjalankan layanan, maka Anda dapat menggunakan layanan latar depan.
Jadi, Anda dapat membuat layanan latar depan . Anda harus menunjukkan pemberitahuan kepada pengguna saat layanan Anda berjalan. Lihat jawaban ini (Ada banyak lainnya)
Solusi jika -
Anda tidak ingin pemberitahuan untuk layanan Anda?
Anda dapat menggunakan tugas berkala dengan Manajer Alarm , Penjadwal Pekerjaan , Evernote-Jobs atau Work Manager .
Saya telah menguji selamanya menjalankan layanan dengan Work-Manager.
sumber
Ya, itu karena Anda tidak dapat memulai layanan di latar belakang lagi di API 26. Jadi Anda dapat memulai ForegroundService di atas API 26.
Anda harus menggunakan
dan memposting pemberitahuan saat memproses kebocoran.
sumber
Seperti @kosev katakan dalam jawabannya Anda dapat menggunakan JobIntentService. Tapi saya menggunakan solusi alternatif - saya menangkap IllegalStateException dan memulai layanan sebagai latar depan. Misalnya, fungsi ini memulai layanan saya:
dan ketika saya memproses Intent saya melakukan hal seperti itu:
sumber
context.startService
bekerja di latar belakang - kadang-kadang tidak - terlihat ini seperti satunya cara terbaik jika Anda harus menerapkan kode lebih banyak di kelas utama Andaextending Application
danimplementing ActivityLifecycleCallbacks
dan melacak apakah aplikasi ini di latar depan atau latar belakang dan mulai niat Anda demikian.Dari catatan rilis firebase , mereka menyatakan bahwa dukungan untuk Android O pertama kali dirilis pada 10.2.1 (walaupun saya akan merekomendasikan menggunakan versi terbaru).
silakan tambahkan dependensi pesan berbasis firebase baru untuk Android O
tingkatkan layanan google play dan repositori google jika diperlukan.
sumber
Jika ada niat yang sebelumnya berfungsi dengan baik ketika aplikasi di latar belakang, itu tidak akan terjadi lagi dari Android 8 dan di atas. Hanya merujuk pada niat yang harus melakukan pemrosesan ketika aplikasi berada di latar belakang.
Langkah-langkah di bawah ini harus diikuti:
JobIntentService
bukanIntentService
.Kelas yang meluas
JobIntentService
harus mengimplementasikanonHandleWork(@NonNull Intent intent)
metode - dan harus memiliki di bawah metode, yang akan memanggilonHandleWork
metode:Panggil
enqueueWork(Context, intent)
dari kelas di mana maksud Anda ditentukan.Kode sampel:
com.android.support:support-compat
diperlukan untukJobIntentService
- saya gunakan26.1.0 V
.Yang paling penting adalah untuk memastikan versi Firebase libraries aktif setidaknya
10.2.1
, saya punya masalah dengan10.2.0
- jika Anda punya!Manifes Anda harus memiliki izin di bawah ini untuk kelas Layanan:
Semoga ini membantu.
sumber
Saya melihat banyak tanggapan yang merekomendasikan hanya menggunakan ForegroundService. Untuk menggunakan ForegroundService harus ada pemberitahuan yang terkait dengannya. Pengguna akan melihat pemberitahuan ini. Bergantung pada situasinya, mereka mungkin terganggu dengan aplikasi Anda dan mencopotnya.
Solusi termudah adalah dengan menggunakan Komponen Arsitektur baru yang disebut WorkManager. Anda dapat melihat dokumentasi di sini: https://developer.android.com/topic/libraries/architecture/workmanager/
Anda cukup mendefinisikan kelas pekerja Anda yang memperpanjang Pekerja.
Kemudian Anda menjadwalkan kapan Anda ingin menjalankannya.
Mudah! Ada banyak cara Anda dapat mengkonfigurasi pekerja. Ini mendukung pekerjaan berulang dan Anda bahkan dapat melakukan hal-hal rumit seperti merantai jika Anda membutuhkannya. Semoga ini membantu.
sumber
WorkManager is intended for tasks that are deferrable—that is, not required to run immediately
... mungkin paling mudah, namun, aplikasi saya membutuhkan layanan latar belakang yang segera mengeksekusi permintaan pengguna!Alternatif solusi dengan menggunakan JobScheduler, dapat memulai layanan di latar belakang dalam interval waktu yang teratur.
Pertama-tama buatlah kelas dengan nama Util.java
Kemudian, buat kelas JobService dinamai TestJobService.java
Setelah itu kelas Penerima BroadCast bernama ServiceReceiver.java
Perbarui file Manifes dengan kode kelas layanan dan penerima
Meninggalkan peluncur main_intent ke file mainActivity.java yang dibuat secara default, dan perubahan pada file MainActivity.java adalah
WOOAAH !! Layanan Latar Belakang dimulai tanpa layanan Foreground
sumber
Jika Anda menjalankan kode pada 8.0 maka aplikasi akan macet. Jadi, mulailah layanan di latar depan. Jika di bawah 8,0 gunakan ini:
Jika di atas atau 8.0 maka gunakan ini:
sumber
java.lang.SecurityException: Permission Denial: startForeground from pid=13708, uid=10087 requires android.permission.FOREGROUND_SERVICE
. Perbaiki di stackoverflow.com/a/52382711/550471jika Anda telah mengintegrasikan pemberitahuan push pesan berbasis firebase,
Tambahkan / perbarui dependensi pesan berbasis firebase baru untuk android O (Android 8.0), karena Batas Eksekusi Latar Belakang .
tingkatkan layanan google play dan repositori google jika diperlukan.
Memperbarui:
sumber
Gunakan
startForegroundService()
sebagai gantistartService()
dan jangan lupa untuk membuatstartForeground(1,new Notification());
dalam layanan Anda dalam waktu 5 detik dari layanan awal.sumber
Karena suara kontroversial pada jawaban ini (+ 4 / -4 pada edit ini), TOLONG LIHAT JAWABAN LAINNYA, PERTAMA DAN GUNAKAN HANYA INI SEBAGAI RESORT TERAKHIR . Saya hanya menggunakan ini sekali untuk aplikasi jaringan yang berjalan sebagai root dan saya setuju dengan pendapat umum bahwa solusi ini tidak boleh digunakan dalam keadaan normal.
Jawaban asli di bawah ini:
Jawaban lainnya semuanya benar, tetapi saya ingin menunjukkan bahwa cara lain untuk menyiasatinya adalah dengan meminta pengguna menonaktifkan pengoptimalan baterai untuk aplikasi Anda (ini biasanya bukan ide yang baik kecuali jika aplikasi Anda terkait sistem). Lihat jawaban ini untuk cara meminta keluar dari optimisasi baterai tanpa membuat aplikasi Anda dilarang di Google Play.
Anda juga harus memeriksa apakah optimisasi baterai dimatikan pada penerima Anda untuk mencegah crash melalui:
sumber
JobScheduler
dan hal-hal ramah baterai . Beberapa aplikasi perlu bekerja pada level yang lebih rendah daripada aplikasi sinkronisasi biasa. Ini adalah solusi alternatif ketika itu tidak berhasil.jangan gunakan di onStartCommand:
ubah saja ke:
dan itu akan berhasil
sumber