यह गाइड **WorkManager** (आधुनिक, अनुशंसित) और **AlarmManager** (सटीक समय के लिए) दोनों का उपयोग करके लोकल नोटिफिकेशन शेड्यूल करने को कवर करता है।
दृष्टिकोण तुलना
| विशेषता | WorkManager | AlarmManager |
|---|---|---|
| बैटरी अनुकूलन | उत्कृष्ट (डोज़-अनुकूल) | मैन्युअल संचालन आवश्यक |
| सटीक समय | नहीं (विंडो-आधारित) | हाँ (setExact के साथ) |
| प्रक्रिया मृत्यु से बचाव | हाँ | हाँ (सटीक अलार्म के साथ) |
| पुनर्प्रयास/बैकऑफ | बिल्ट-इन | मैन्युअल |
| अनुमति आवश्यक | नहीं | SCHEDULE_EXACT_ALARM (API 31+) |
| सर्वोत्तम लिए | आवधिक सिंक, बैकअप, रिमाइंडर | अलार्म घड़ी, कैलेंडर इवेंट, सटीक रिमाइंडर |
विधि 1: WorkManager (अनुशंसित)
निर्भरताएँ
dependencies {
implementation "androidx.work:work-runtime-ktx:2.9.0"
}
NotificationWorker.java
package com.example.schedulednotification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
public class NotificationWorker extends Worker {
public static final String CHANNEL_ID = "scheduled_work_channel";
private static final String CHANNEL_NAME = "शेड्यूल्ड वर्क नोटिफिकेशन";
public NotificationWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull
@Override
public Result doWork() {
// इनपुट डेटा से पैरामीटर प्राप्त करें
String title = getInputData().getString("title");
String message = getInputData().getString("message");
showNotification(
title != null ? title : "शेड्यूल्ड नोटिफिकेशन",
message != null ? message : "WorkManager के माध्यम से डिलीवर किया गया"
);
return Result.success();
}
private void showNotification(String title, String message) {
createChannelIfNeeded();
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
NotificationManager manager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify((int) System.currentTimeMillis(), builder.build());
}
private void createChannelIfNeeded() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager manager = getApplicationContext().getSystemService(NotificationManager.class);
if (manager.getNotificationChannel(CHANNEL_ID) == null) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("WorkManager के माध्यम से शेड्यूल्ड");
manager.createNotificationChannel(channel);
}
}
}
}
MainActivity.java - WorkManager शेड्यूलिंग
package com.example.schedulednotification;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.Data;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private static final String ONCE_WORK = "once_notification_work";
private static final String PERIODIC_WORK = "periodic_notification_work";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnOnce = findViewById(R.id.btnOnce);
Button btnPeriodic = findViewById(R.id.btnPeriodic);
Button btnCancel = findViewById(R.id.btnCancel);
btnOnce.setOnClickListener(v -> scheduleOnce());
btnPeriodic.setOnClickListener(v -> schedulePeriodic());
btnCancel.setOnClickListener(v -> cancelAll());
}
/** एक बार नोटिफिकेशन शेड्यूल करें */
private void scheduleOnce() {
Data inputData = new Data.Builder()
.putString("title", "एक बार नोटिफिकेशन")
.putString("message", "यह 30 सेकंड बाद दिखाई देगा")
.build();
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setInitialDelay(30, TimeUnit.SECONDS)
.setInputData(inputData)
.build();
WorkManager.getInstance(this).enqueueUniqueWork(
ONCE_WORK, ExistingWorkPolicy.REPLACE, work);
Toast.makeText(this, "30 सेकंड में एक बार नोटिफिकेशन शेड्यूल्ड", Toast.LENGTH_SHORT).show();
}
/** आवधिक नोटिफिकेशन शेड्यूल करें (न्यूनतम 15 मिनट) */
private void schedulePeriodic() {
Data inputData = new Data.Builder()
.putString("title", "आवधिक नोटिफिकेशन")
.putString("message", "हर 30 मिनट में दोहराता है")
.build();
PeriodicWorkRequest work = new PeriodicWorkRequest.Builder(NotificationWorker.class, 30, TimeUnit.MINUTES)
.setInputData(inputData)
.build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
PERIODIC_WORK, ExistingPeriodicWorkPolicy.KEEP, work);
Toast.makeText(this, "आवधिक नोटिफिकेशन शेड्यूल्ड (हर 30 मिनट)", Toast.LENGTH_SHORT).show();
}
private void cancelAll() {
WorkManager.getInstance(this).cancelUniqueWork(ONCE_WORK);
WorkManager.getInstance(this).cancelUniqueWork(PERIODIC_WORK);
Toast.makeText(this, "सभी शेड्यूल्ड कार्य रद्द किए गए", Toast.LENGTH_SHORT).show();
}
}
विधि 2: AlarmManager (सटीक समय के लिए)
जब आपको **सटीक मिनट/सेकंड डिलीवरी** की आवश्यकता हो (उदाहरण के लिए, अलार्म घड़ी, कैलेंडर अलर्ट)।
ExactAlarmReceiver.java
package com.example.schedulednotification;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import androidx.core.app.NotificationCompat;
public class ExactAlarmReceiver extends BroadcastReceiver {
public static final String CHANNEL_ID = "exact_alarm_channel";
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager manager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
String title = intent.getStringExtra("title");
String message = intent.getStringExtra("message");
int id = intent.getIntExtra("id", (int) System.currentTimeMillis());
createChannelIfNeeded(manager);
Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(title != null ? title : "सटीक अलार्म")
.setContentText(message != null ? message : "निर्दिष्ट समय पर डिलीवर किया गया")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
manager.notify(id, notification);
}
private void createChannelIfNeeded(NotificationManager manager) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (manager.getNotificationChannel(CHANNEL_ID) == null) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, "सटीक अलार्म नोटिफिकेशन", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("सटीक समय पर डिलीवर किया गया");
manager.createNotificationChannel(channel);
}
}
}
}
MainActivity.java में शेड्यूलिंग जोड़ें
// MainActivity में जोड़ें:
private void scheduleExactAlarm() {
// सटीक अलार्म अनुमति जांचें (Android 12+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (!alarmManager.canScheduleExactAlarms()) {
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
startActivityForResult(intent, 1002);
return;
}
}
Intent intent = new Intent(this, ExactAlarmReceiver.class);
intent.putExtra("title", "सटीक अलार्म");
intent.putExtra("message", "सटीक समय पर डिलीवर किया गया!");
intent.putExtra("id", 9999);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 9999, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
long triggerTime = System.currentTimeMillis() + 20_000; // 20 सेकंड बाद
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}
Toast.makeText(this, "सटीक अलार्म 20 सेकंड के लिए सेट", Toast.LENGTH_SHORT).show();
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.schedulednotification">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ScheduledNotification">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".ExactAlarmReceiver"
android:exported="false">
</receiver>
</application>
</manifest>
layout/activity_main.xml (अपडेटेड)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<Button
android:id="@+id/btnOnce"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="एक बार नोटिफिकेशन (30 सेकंड)"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btnPeriodic"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="आवधिक नोटिफिकेशन (हर 30 मिनट)"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/btnOnce"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btnExact"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="सटीक अलार्म (20 सेकंड)"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/btnPeriodic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="सभी रद्द करें"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/btnExact"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
कौन सा चुनें?
- WorkManager → 95% उपयोग के मामले: रिमाइंडर, सिंक, बैकअप, दैनिक सारांश
- AlarmManager (सटीक) → अलार्म घड़ी, कैलेंडर इवेंट, दवा रिमाइंडर जहाँ सेकंड मायने रखते हैं
- FCM → सर्वर-ट्रिगर्ड नोटिफिकेशन
महत्वपूर्ण नोट्स
- WorkManager आवधिक कार्य के लिए **न्यूनतम 15 मिनट** अंतराल लागू करता है
- Android 12+ पर सटीक अलार्म के लिए **SCHEDULE_EXACT_ALARM** अनुमति आवश्यक
- दोनों दृष्टिकोणों के लिए **नोटिफिकेशन चैनल** अनिवार्य (API 26+)
- Android 13+ पर **POST_NOTIFICATIONS** रनटाइम अनुमति आवश्यक