📱 Device Features · Lesson 38
WorkManager, Services और Broadcasts
Background काम के लिए कौन सा tool?
| ज़रूरत | Use |
|---|---|
| Screen खुली रहते काम (data load) | viewModelScope में Coroutines |
| App बंद हो तब भी पूरा हो: reminders, uploads, sync | WorkManager |
| User को दिखने वाला ongoing काम: music, navigation, workout tracking | Foreground Service |
| Exact clock time (alarm app) | AlarmManager (exact alarms) |
Setup
TOML + Kotlin DSL
# libs.versions.toml
work = "2.10.0"
androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
// app/build.gradle.kts
implementation(libs.androidx.work.runtime.ktx)Step 1: Worker लिखें
Kotlin – reminder/ReminderWorker.kt
package com.codingeasily.studentdiary.reminder
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.codingeasily.studentdiary.R
import com.codingeasily.studentdiary.data.AppDatabase
import com.codingeasily.studentdiary.data.SettingsStore
/** WorkManager runs this at the reminder time, even if the app was closed. */
class ReminderWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val noteId = inputData.getLong(KEY_NOTE_ID, -1L)
if (noteId == -1L || !SettingsStore(applicationContext).remindersEnabled) return Result.success()
val note = AppDatabase.get(applicationContext).noteDao().getById(noteId)
?: return Result.success() // note was deleted
if (note.isDone) return Result.success()
NotificationHelper.show(
applicationContext,
note.id,
applicationContext.getString(R.string.reminder_title, note.title),
note.content.ifBlank { note.subject }
)
return Result.success()
}
companion object {
const val KEY_NOTE_ID = "note_id"
}
}| Return | मतलब |
|---|---|
| Result.success() | हो गया |
| Result.retry() | Backoff के साथ बाद में फिर |
| Result.failure() | छोड़ दो |
Step 2: Schedule करें
Kotlin – reminder/ReminderScheduler.kt
package com.codingeasily.studentdiary.reminder
import android.content.Context
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import java.util.concurrent.TimeUnit
object ReminderScheduler {
private fun workName(noteId: Long) = "reminder_$noteId"
/** Schedules (or re-schedules) one reminder for a note. */
fun schedule(context: Context, noteId: Long, atMillis: Long) {
val delay = atMillis - System.currentTimeMillis()
if (delay <= 0) return
val request = OneTimeWorkRequestBuilder<ReminderWorker>()
.setInitialDelay(delay, TimeUnit.MILLISECONDS)
.setInputData(workDataOf(ReminderWorker.KEY_NOTE_ID to noteId))
.build()
WorkManager.getInstance(context)
.enqueueUniqueWork(workName(noteId), ExistingWorkPolicy.REPLACE, request)
}
fun cancel(context: Context, noteId: Long) {
WorkManager.getInstance(context).cancelUniqueWork(workName(noteId))
}
}असली example: note reminders
Kotlin
// NoteViewModel.save() – schedule or cancel when a note is saved val id = repo.save(note) val due = note.dueAt if (due != null && !note.isDone) ReminderScheduler.schedule(getApplication(), id, due) else ReminderScheduler.cancel(getApplication(), id)
Periodic work और constraints
Kotlin
class BackupWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result = try {
uploadNotesToServer()
Result.success()
} catch (e: IOException) {
Result.retry() // WorkManager tries again later (backoff)
}
}
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) // Wi-Fi only
.setRequiresCharging(true)
.build()
val daily = PeriodicWorkRequestBuilder<BackupWorker>(1, TimeUnit.DAYS)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork("daily_backup", ExistingPeriodicWorkPolicy.KEEP, daily)Work status observe करें
Kotlin
WorkManager.getInstance(requireContext())
.getWorkInfosForUniqueWorkLiveData("daily_backup")
.observe(viewLifecycleOwner) { infos ->
val state = infos.firstOrNull()?.state
binding.tvBackup.text = "Backup: ${state ?: "not scheduled"}" // ENQUEUED, RUNNING, SUCCEEDED…
}Android Studio → App Inspection → Background Task Inspector सारा scheduled और running work दिखाता है।
Foreground Service (music, tracking)
XML + Kotlin
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<service
android:name=".PlayerService"
android:exported="false"
android:foregroundServiceType="mediaPlayback" />
// PlayerService.kt
class PlayerService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = NotificationCompat.Builder(this, "player")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Playing: Kotlin lecture 3")
.build()
startForeground(1, notification) // must be called within a few seconds
// … start playback
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
}
// start it
ContextCompat.startForegroundService(this, Intent(this, PlayerService::class.java))आम गलतियाँ
- Uploads के लिए plain background Service → Android 8+ पर kill; WorkManager use करें।
- Reminders के लिए non-unique work → हर edit पर duplicates; REPLACE के साथ
enqueueUniqueWorkuse करें। - Input data में बड़े objects (10 KB limit) → id भेजें और Room से पढ़ें।
- Android 14 पर
foregroundServiceTypeके बिना foreground service → crash।
सारांश
- WorkManager = guaranteed background work; suspend code के लिए CoroutineWorker।
- Reminders के लिए delay वाला OneTime, sync के लिए constraints वाला Periodic (≥15 min)।
- Foreground Service सिर्फ़ ongoing, user को दिखने वाले कामों के लिए।
✅ Practice
PeriodicWorkRequest से लगभग 7 PM पर daily "Revision time!" notification schedule कीजिए, और उसका status (ENQUEUED/RUNNING) Settings screen पर दिखाइए।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
क्या WorkManager exact time पर चलता है?
बिल्कुल exact नहीं। WorkManager काम चलने की guarantee देता है, पर battery बचाने के लिए (Doze) system थोड़ी देर कर सकता है। Alarm-clock जैसी accuracy के लिए exact-alarm permission के साथ AlarmManager.setExactAndAllowWhileIdle use करें।
Periodic work का minimum interval क्या है?
15 मिनट। छोटे intervals 15 मिनट तक बढ़ा दिए जाते हैं।
क्या phone restart के बाद work बचा रहता है?
हाँ। WorkManager scheduled work अपने database में रखता है और reboot के बाद फिर schedule करता है।
