यह ट्यूटोरियल दर्शाता है कि **BroadcastReceiver** के साथ **AlarmManager** का उपयोग करके नोटिफिकेशन कैसे बनाए और शेड्यूल किए जाएँ। यह पैटर्न ऐप प्रोसेस न चलने पर भी सटीक समय-आधारित डिलीवरी सक्षम करता है।
आर्किटेक्चर अवलोकन
MainActivity → AlarmManager.setExact() → PendingIntent (Broadcast)
→ MyNotificationPublisher (BroadcastReceiver) → NotificationManager.notify()
चरण 1: निर्भरताएँ और अनुमतियाँ
<!-- AndroidManifest.xml में --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <!-- Android 12+ --> <uses-permission android:name="android.permission.USE_EXACT_ALARM" /> <!-- Android 13+ -->
चरण 2: लेआउट (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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="नोटिफिकेशन शेड्यूल करने के लिए देरी चुनें:"
android:textSize="16sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/btn5sec"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="5 सेकंड में शेड्यूल करें"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/textView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btn10sec"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="10 सेकंड में शेड्यूल करें"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/btn5sec"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Button
android:id="@+id/btn30sec"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="30 सेकंड में शेड्यूल करें"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@id/btn10sec"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
चरण 3: BroadcastReceiver - नोटिफिकेशन प्रकाशक
package com.example.broadcastnotification;
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 MyNotificationPublisher extends BroadcastReceiver {
public static final String NOTIFICATION_ID = "notification_id";
public static final String NOTIFICATION = "notification";
public static final String CHANNEL_ID = "scheduled_channel";
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager manager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
// MainActivity से पास किया गया नोटिफिकेशन प्राप्त करें
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
// चैनल सुनिश्चित करें (प्राप्तकर्ता प्रक्रिया में चल सकता है)
createChannelIfNeeded(manager);
assert manager != null;
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("AlarmManager के माध्यम से शेड्यूल्ड नोटिफिकेशन");
manager.createNotificationChannel(channel);
}
}
}
}
चरण 4: MainActivity.java - शेड्यूलिंग लॉजिक
package com.example.broadcastnotification;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final String CHANNEL_ID = "scheduled_channel";
private static final int PERMISSION_REQUEST_CODE = 1001;
private static final int EXACT_ALARM_REQUEST_CODE = 1002;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createNotificationChannel();
requestPermissionsIfNeeded();
Button btn5 = findViewById(R.id.btn5sec);
Button btn10 = findViewById(R.id.btn10sec);
Button btn30 = findViewById(R.id.btn30sec);
btn5.setOnClickListener(v -> scheduleNotification("5 सेकंड विलंब", 5000));
btn10.setOnClickListener(v -> scheduleNotification("10 सेकंड विलंब", 10000));
btn30.setOnClickListener(v -> scheduleNotification("30 सेकंड विलंब", 30000));
}
private void requestPermissionsIfNeeded() {
// नोटिफिकेशन अनुमति (Android 13+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.POST_NOTIFICATIONS}, PERMISSION_REQUEST_CODE);
}
}
// सटीक अलार्म अनुमति (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, EXACT_ALARM_REQUEST_CODE);
}
}
}
private void scheduleNotification(String content, long delayMillis) {
// नोटिफिकेशन ऑब्जेक्ट बनाएँ
Notification notification = buildNotification(content);
// BroadcastReceiver को ट्रिगर करने के लिए इंटेंट
Intent publisherIntent = new Intent(this, MyNotificationPublisher.class);
publisherIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, 1);
publisherIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
// ब्रॉडकास्ट के लिए PendingIntent (एक्टिविटी नहीं!)
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0, publisherIntent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
// AlarmManager के साथ शेड्यूल करें
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long triggerTime = SystemClock.elapsedRealtime() + delayMillis;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// सटीक डिलीवरी के लिए setExactAndAllowWhileIdle
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime,
pendingIntent);
} else {
alarmManager.setExact(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
triggerTime,
pendingIntent);
}
Toast.makeText(this, "शेड्यूल्ड: " + content, Toast.LENGTH_SHORT).show();
}
private Notification buildNotification(String content) {
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("शेड्यूल्ड नोटिफिकेशन")
.setContentText(content)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setChannelId(CHANNEL_ID)
.build();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, "शेड्यूल्ड नोटिफिकेशन", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("BroadcastReceiver + AlarmManager के माध्यम से डिलीवर किया गया");
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}
}
चरण 5: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.broadcastnotification">
<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.BroadcastNotification">
<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>
<!-- BroadcastReceiver घोषणा -->
<receiver
android:name=".MyNotificationPublisher"
android:exported="false"> <!-- आंतरिक उपयोग के लिए false -->
</receiver>
</application>
</manifest>
मुख्य अवधारणाएँ समझाई गईं
क्यों BroadcastReceiver?
- हल्का: पूर्ण एक्टिविटी लॉन्च नहीं करता
- पृष्ठभूमि निष्पादन: ऐप प्रोसेस मारे जाने पर भी काम करता है
- AlarmManager के साथ संगत: `getBroadcast()` के लिए डिज़ाइन किया गया
AlarmManager विधियाँ
| विधि | API स्तर | सटीकता | डोज़ मोड |
|---|---|---|---|
set() | 19+ | असटीक (बैच्ड) | डोज़ में विलंबित |
setExact() | 19+ | सटीक | डोज़ में विलंबित |
setExactAndAllowWhileIdle() | 23+ | सटीक | डोज़ में भी चलता है |
setAlarmClock() | 21+ | सटीक, उपयोगकर्ता-दृश्यमान | कभी विलंबित नहीं |
PendingIntent प्रकार
// BroadcastReceiver के लिए (यहां उपयोग किया गया): PendingIntent.getBroadcast(context, requestCode, intent, flags) // Activity के लिए: PendingIntent.getActivity(context, requestCode, intent, flags) // Service के लिए: PendingIntent.getService(context, requestCode, intent, flags) // Foreground Service के लिए (Android 12+): PendingIntent.getForegroundService(context, requestCode, intent, flags)
आधुनिक विकल्प: WorkManager
अधिकांश शेड्यूलिंग आवश्यकताओं के लिए, **WorkManager** को प्राथमिकता दी जाती है:
- बैटरी-अनुकूलित
- सटीक समय की आवश्यकता नहीं
- प्रक्रिया मृत्यु से बचता है
- बैकऑफ/पुनर्प्रयास नीतियों का समर्थन करता है
// WorkManager समतुल्य:
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(NotificationWorker.class)
.setInitialDelay(10, TimeUnit.SECONDS)
.build();
WorkManager.getInstance(context).enqueue(work);
सर्वोत्तम अभ्यास
- सटीक अलार्म अनुमति Android 12+ पर रनटाइम पर अनुरोध करें
- FLAG_IMMUTABLE | FLAG_UPDATE_CURRENT PendingIntent के लिए उपयोग करें
- रिसीवर में चैनल बनाएँ - यह ऐप प्रोसेस से अलग प्रक्रिया में चल सकता है
- exported="false" आंतरिक रिसीवर के लिए
- अद्वितीय अनुरोध कोड प्रत्येक शेड्यूल्ड नोटिफिकेशन के लिए टकराव से बचने के लिए