यह व्यापक गाइड एंड्रॉइड में नोटिफिकेशन शेड्यूल करने के **तीन प्रमुख तरीकों** को कवर करता है: WorkManager (आधुनिक मानक), AlarmManager (सटीक समय), और Handler (सरल अल्पकालिक विलंब)।
त्वरित निर्णय मार्गदर्शिका
| आवश्यकता | अनुशंसित दृष्टिकोण |
|---|---|
| विश्वसनीय, बैटरी-कुशल, लचीला समय | WorkManager |
| सटीक सेकंड/मिनट डिलीवरी (अलार्म घड़ी) | AlarmManager.setExactAndAllowWhileIdle() |
| सरल अल्पकालिक विलंब (< 1 मिनट, ऐप अग्रभूमि में) | Handler.postDelayed() |
| सर्वर से पुश नोटिफिकेशन | Firebase Cloud Messaging (FCM) |
विधि 1: WorkManager (सर्वोत्तम ऑल-राउंडर)
निर्भरताएँ
dependencies {
implementation "androidx.work:work-runtime-ktx:2.9.0"
}
NotificationWorker.java
package com.example.schedulenotification;
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 = "workmanager_channel";
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, message);
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 != null ? title : "शेड्यूल्ड नोटिफिकेशन")
.setContentText(message != null ? message : "WorkManager के माध्यम से डिलीवर किया गया")
.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, "WorkManager नोटिफिकेशन", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
}
}
}
शेड्यूलिंग कोड (कहीं भी - एक्टिविटी, फ्रैगमेंट, सर्विस)
// एक बार नोटिफिकेशन (विलंब के साथ)
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setInitialDelay(30, TimeUnit.SECONDS) // या .setInitialDelay(2, TimeUnit.HOURS)
.setInputData(new Data.Builder()
.putString("title", "कस्टम शीर्षक")
.putString("message", "कस्टम संदेश")
.build())
.build();
WorkManager.getInstance(context).enqueueUniqueWork(
"unique_work_name", ExistingWorkPolicy.REPLACE, work);
// आवधिक नोटिफिकेशन (न्यूनतम 15 मिनट अंतराल)
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(
NotificationWorker.class, 30, TimeUnit.MINUTES)
.setInputData(inputData)
.build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"periodic_work_name", ExistingPeriodicWorkPolicy.KEEP, periodicWork);
// रद्द करना
WorkManager.getInstance(context).cancelUniqueWork("unique_work_name");
विधि 2: AlarmManager (सटीक समय)
अलार्म घड़ी, कैलेंडर इवेंट, दवा रिमाइंडर के लिए आवश्यक।
ExactAlarmReceiver.java
package com.example.schedulenotification;
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);
manager.createNotificationChannel(channel);
}
}
}
}
सटीक अलार्म शेड्यूल करना
private void scheduleExactNotification(Context context, String title, String message,
long triggerAtMillis, int requestCode) {
// Android 12+ पर अनुमति जांचें
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (!alarmManager.canScheduleExactAlarms()) {
// उपयोगकर्ता को सेटिंग्स पर भेजें
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return;
}
}
Intent intent = new Intent(context, ExactAlarmReceiver.class);
intent.putExtra("title", title);
intent.putExtra("message", message);
intent.putExtra("id", requestCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, requestCode, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// डोज़ मोड में भी चलता है
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
}
}
// उपयोग: ठीक 10:30 AM के लिए
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_YEAR, 1); // कल यदि समय बीत चुका है
}
scheduleExactNotification(this, "दवा रिमाइंडर", "अपनी दवा लें",
calendar.getTimeInMillis(), 1001);
विधि 3: Handler (सरल, अल्पकालिक, केवल अग्रभूमि)
केवल तभी उपयोग करें जब ऐप अग्रभूमि में हो और विलंब छोटा हो (< 60 सेकंड)।
// एक्टिविटी/फ्रैगमेंट में:
int notificationId = (int) System.currentTimeMillis();
showNotificationNow(notificationId); // आपका मौजूदा नोटिफिकेशन कोड
// 10 सेकंड बाद ऑटो-कैंसिल शेड्यूल करें
new Handler(Looper.getMainLooper()).postDelayed(() -> {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(notificationId);
}, 10_000);
// या आधुनिक API (API 26+):
// builder.setTimeoutAfter(10_000); // स्वतः कैंसिल, कोई हैंडलर आवश्यक नहीं
AndroidManifest.xml (संयुक्त)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.schedulenotification">
<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.ScheduleNotification">
<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>
WorkManager उन्नत सुविधाएँ
बाधाएँ (Constraints)
// केवल चार्जिंग पर और अनमीटर्ड नेटवर्क पर चलाएँ
Constraints constraints = new Constraints.Builder()
.setRequiresCharging(true)
.setRequiredNetworkType(NetworkType.UNMETERED)
.build();
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setConstraints(constraints)
.setInitialDelay(1, TimeUnit.HOURS)
.build();
बैकऑफ और पुनर्प्रयास
// घातीय बैकऑफ के साथ पुनर्प्रयास
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
.build();
कार्य श्रृंखला
WorkManager.getInstance(context)
.beginWith(workA)
.then(workB)
.then(workC)
.enqueue();
सर्वोत्तम अभ्यास चेकलिस्ट
- [ ] **WorkManager** डिफ़ॉल्ट विकल्प के रूप में उपयोग करें
- [ ] **AlarmManager** केवल तब उपयोग करें जब सटीक समय महत्वपूर्ण हो
- [ ] **सटीक अलार्म अनुमति** Android 12+ पर रनटाइम पर अनुरोध करें
- [ ] **नोटिफिकेशन चैनल** दोनों दृष्टिकोणों में बनाएँ (रिसीवर/वर्कर में भी)
- [ ] **POST_NOTIFICATIONS** Android 13+ पर रनटाइम पर अनुरोध करें
- [ ] **FLAG_IMMUTABLE | FLAG_UPDATE_CURRENT** PendingIntent के लिए
- [ ] **अद्वितीय कार्य नाम** डुप्लिकेट शेड्यूलिंग रोकने के लिए
- [ ] **डोज़/ऐप स्टैंडबाय** के साथ परीक्षण करें (ADB: `dumpsys deviceidle force-idle`)
परीक्षण आदेश
# डोज़ मोड बल करें adb shell dumpsys deviceidle force-idle # ऐप स्टैंडबाय बल करें adb shell am set-standby-bucket com.example.schedulenotification restricted # लंबित अलार्म जांचें adb shell dumpsys alarm | grep com.example.schedulenotification # WorkManager स्थिति जांचें adb shell dumpsys jobscheduler | grep com.example.schedulenotification