이 글에서는 Android에서 알림을 통해 서비스(Service)를 시작하는 방법을 단계별로 살펴봅니다. 알림 클릭 시 특정 시점에 자동으로 서비스가 실행되도록 AlarmManager와 PendingIntent를 활용하는 실전 예제입니다.
개요
Android에서 백그라운드 작업을 예약 실행하려면 AlarmManager를 사용하고, 이를 사용자에게 알려주기 위해 알림(Notification)을 함께 구성할 수 있습니다. 아래 예제는 매일 정해진 시간에 반복적으로 서비스를 호출하고, 해당 서비스가 알림을 생성하는 흐름을 보여줍니다.
Step 1 — 새 프로젝트 생성
Android Studio에서 File ⇒ New Project로 이동한 뒤, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.
Step 2 — activity_main.xml 작성
res/layout/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:onClick="createNotification"
android:text="create notification"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>Step 3 — MainActivity 작성
src/MainActivity.java에 다음 코드를 추가합니다. 버튼 클릭 시 AlarmManager가 익일 오전 12시부터 하루 간격으로 NotifyService를 반복 호출하도록 설정합니다.
package app.tutorialspoint.com.notifyme;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
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 myIntent = new Intent(getApplicationContext(), NotifyService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
1000 * 60 * 60 * 24, pendingIntent);
}
}Step 4 — NotifyService 작성
src/NotifyService.java에 다음 코드를 추가합니다. 서비스가 실행되면 채널을 생성하고 알림을 화면에 표시합니다. Android 8.0(Oreo, API 26) 이상에서는 반드시 NotificationChannel을 생성해야 한다는 점에 유의하세요.
package app.tutorialspoint.com.notifyme;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
public class NotifyService extends Service {
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private final static String default_notification_channel_id = "default";
public NotifyService() {
}
@Override
public IBinder onBind(Intent intent) {
Intent notificationIntent = new Intent(getApplicationContext(),
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, 0);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
getApplicationContext(), default_notification_channel_id);
mBuilder.setContentTitle("My Notification");
mBuilder.setContentIntent(pendingIntent);
mBuilder.setContentText("Notification Listener Service Example");
mBuilder.setSmallIcon(R.drawable.ic_launcher_foreground);
mBuilder.setAutoCancel(true);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID,
"NOTIFICATION_CHANNEL_NAME", importance);
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
assert mNotificationManager != null;
mNotificationManager.createNotificationChannel(notificationChannel);
}
assert mNotificationManager != null;
mNotificationManager.notify((int) System.currentTimeMillis(),
mBuilder.build());
throw new UnsupportedOperationException("Not yet implemented");
}
}Step 5 — AndroidManifest.xml 수정
AndroidManifest.xml에 아래 코드를 추가합니다. 진동 권한과 부팅 완료 수신 권한을 선언하고, <service> 태그 안에 서비스를 등록해야 합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.tutorialspoint.com.notifyme">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<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/AppTheme">
<service
android:name=".NotifyService"
android:enabled="true"
android:exported="true">
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>앱 실행 및 확인
이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바에서 Run 아이콘을 클릭하세요. 실행 옵션에서 본인의 모바일 기기를 선택하면, 기기의 기본 화면에 아래와 같은 결과가 표시됩니다.

마무리
이처럼 AlarmManager와 PendingIntent를 조합하면 특정 시간에 서비스를 자동으로 실행하고, 서비스 내에서 알림을 생성해 사용자에게 정보를 전달할 수 있습니다. 참고로 Android 8.0 이상에서는 배터리 최적화 정책으로 인해 백그라운드 제약이 강화되었으므로, 실제 앱 개발 시에는 JobScheduler, WorkManager 또는 Foreground Service 사용도 함께 고려하는 것이 좋습니다.