নোটিফিকেশন ইন্টারঅ্যাকশন দিয়ে সার্ভিস লঞ্চ করা
এই টিউটোরিয়ালে দেখানো হয়েছে কীভাবে একটি নোটিফিকেশনের মাধ্যমে ব্যাকগ্রাউন্ড সার্ভিস (Service) শুরু করা যায়। আমরা AlarmManager ব্যবহার করে পরاয়ন নোটিফিকেশন তৈরি করব এবং সেটি থেকে একটি Service শুরু করব।
আর্কিটেকচার ওভারভিউ
- MainActivity → AlarmManager সেট করে → নির্দিষ্ট সময়ে সার্ভিস ট্রিগার
- NotifyService →extends Service → নোটিফিকেশন তৈরি ও প্রদর্শন
- AlarmManager.RTC_WAKEUP → ডিভাইস স্লিপ থাকলেও জাগিয়ে দেয়
ধাপ ১: নতুন প্রজেক্ট
Package name: com.example.notifyservice
ধাপ ২: লেআউট (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
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/btnStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="createNotification"
android:text="দৈনিক নোটিফিকেশন শিডিউল করুন" />
</RelativeLayout>
ধাপ ৩: MainActivity.java — AlarmManager সেটআপ
package com.example.notifyservice;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void createNotification(View view) {
// সার্ভিস শুরু করার Intent
Intent serviceIntent = new Intent(this, NotifyService.class);
// PendingIntent for Service
PendingIntent pendingIntent = PendingIntent.getService(
this, 0, serviceIntent, PendingIntent.FLAG_IMMUTABLE);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// পরের দিন সকাল ১২:০০ AM এ শুরু
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.DAY_OF_MONTH, 1); // পরের দিন
// প্রতিদিন রিপিট (24 ঘণ্টা = 1000*60*60*24 ms)
long interval = 1000L * 60 * 60 * 24;
if (alarmManager != null) {
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
interval,
pendingIntent
);
}
}
}
ধাপ ৪: NotifyService.java — নোটিফিকেশন তৈরি
package com.example.notifyservice;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import androidx.core.app.NotificationCompat;
public class NotifyService extends Service {
public static final String CHANNEL_ID = "notify_service_channel";
private static final String DEFAULT_CHANNEL = "default";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
showNotification();
// কাজ শেষ হলে self-stop
stopSelf();
return START_NOT_STICKY;
}
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra("fromNotification", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL)
.setContentTitle("দৈনিক রিমাইন্ডার")
.setContentText("আপনার দৈনিক কাজের সময় হয়েছে!")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, "দৈনিক নোটিফিকেশন",
NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
builder.setChannelId(CHANNEL_ID);
}
manager.notify((int) System.currentTimeMillis(), builder.build());
}
@Override
public IBinder onBind(Intent intent) {
return null; // বাইন্ডিং সমর্থন করছে না
}
}
ধাপ ৫: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.notifyservice">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Android 12+ জন্য exact alarm permission -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<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.NotifyService">
<service
android:name=".NotifyService"
android:enabled="true"
android:exported="false" />
<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>
</application>
</manifest>
গুরুত্বপূর্ণ আপডেট: Android 12+ (API 31+)
Android 12 থেকে setExact() এবং setRepeating() এর জন্য SCHEDULE_EXACT_ALARM পারমিশন দরকার। মেনিফেস্টে যোগ করুন এবং রানটাইমে চেক করুন:
// MainActivity-তে onCreate-এ বা বাটন ক্লিকের আগে
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (alarmManager != null && !alarmManager.canScheduleExactAlarms()) {
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
startActivity(intent);
return; // ব্যবহারকারী অনুমতি দিলে আবার চেষ্টা করুন
}
}
বিকল্প: WorkManager ব্যবহার (সুপারিশ করা)
আধুনিক Android-এ (API 23+) পিরিয়ডিক ব্যাকগ্রাউন্ড কাজের জন্য WorkManager সুপারিশ করা হয়। এটি ডজ মোড, অ্যাপ স্ট্যান্ডবাই, বুট কমপ্লিট ইত্যাদি হ্যান্ডেল করে।
// build.gradle (app)
implementation "androidx.work:work-runtime-ktx:2.9.0"
// PeriodicWorkRequest (প্রতি ২৪ ঘণ্টা)
PeriodicWorkRequest notifyWork = new PeriodicWorkRequest.Builder(
NotifyWorker.class, 24, TimeUnit.HOURS).build();
WorkManager.getInstance(context).enqueue(notifyWork);
পরীক্ষা পদ্ধতি
- অ্যাপ ইনস্টল করুন → "দৈনিক নোটিফিকেশন শিডিউল করুন" চাপুন
- ডিভাইস রিবুট করুন → নোটিফিকেশন এসে কিনা চেক করুন (BOOT_COMPLETED রিসিভার যোগ করলে)
- লগক্যাটে
NotifyServiceচালু হয়েছে কিনা দেখুন
সাধারণ সমস্যা ও সমাধান
| সমস্যা | সমাধান |
|---|---|
| সার্ভিস কল হয় না | Manifest-এ service exported=false, PendingIntent.FLAG_IMMUTABLE ব্যবহার করুন |
| রিপিট হয় না | Android 6+ Doze মোডে setRepeating ইনএক্সেক্ট হয়; setExact + reschedule বা WorkManager ব্যবহার করুন |
| নোটিফিকেশন দেখাচ্ছে না | Notification Channel তৈরি হয়েছে কিনা, IMPORTANCE_HIGH সেট করুন |