Android에서 특정 시간에 매일 알림 생성하기
이 튜토리얼에서는 Android 앱에서 AlarmManager와 BroadcastReceiver를 활용하여 사용자가 지정한 날짜와 시간에 알림을 예약하고 표시하는 방법을 단계별로 살펴봅니다.
작동 원리 요약: 사용자가 날짜를 선택하면 DatePickerDialog가 Calendar 객체에 해당 값을 저장하고, AlarmManager가 지정된 시각에 브로드캐스트를 발송하도록 예약합니다. 이후 BroadcastReceiver인 MyNotificationPublisher가 이를 수신하여 알림 채널(Android 8.0 오레오 이상)을 생성하고 알림을 게시합니다.
1단계: 새 프로젝트 생성
Android Studio에서 File ⇒ New Project를 선택하여 새 프로젝트를 만들고, 필요한 모든 세부 정보를 입력합니다.
2단계: 레이아웃 파일 작성
res/layout/activity_main.xml에 아래 코드를 추가합니다. 날짜를 선택할 수 있는 TextView 하나로 구성된 간단한 화면입니다.
<? 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" >
<TextView
android :id = "@+id/tvDate"
android :layout_width = "match_parent"
android :layout_height = "wrap_content"
android :hint = "Select Date"
android :onClick = "setDate"
android :padding = "16dp" />
</RelativeLayout>
3단계: MainActivity 구현
src/MainActivity에 다음 코드를 추가합니다. 이 클래스에서는 날짜 선택 다이얼로그를 띄우고, 선택된 날짜에 맞춰 알림을 예약하는 핵심 로직이 처리됩니다.
package app.tutorialspoint.com.notifyme ;
import android.app.AlarmManager ;
import android.app.DatePickerDialog ;
import android.app.Notification ;
import android.app.PendingIntent ;
import android.content.Context ;
import android.content.Intent ;
import android.os.Bundle ;
import android.support.v4.app.NotificationCompat ;
import android.support.v7.app.AppCompatActivity ;
import android.view.View ;
import android.widget.Button ;
import android.widget.DatePicker ;
import java.text.SimpleDateFormat ;
import java.util.Calendar ;
import java.util.Date ;
import java.util.Locale ;
public class MainActivity extends AppCompatActivity {
public static final String NOTIFICATION_CHANNEL_ID = "10001" ;
private final static String default_notification_channel_id = "default" ;
Button btnDate ;
final Calendar myCalendar = Calendar. getInstance () ;
@Override
protected void onCreate (Bundle savedInstanceState) {
super .onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main ) ;
btnDate = findViewById(R.id. btnDate ) ;
}
private void scheduleNotification (Notification notification , long delay) {
Intent notificationIntent = new Intent( this, MyNotificationPublisher. class ) ;
notificationIntent.putExtra(MyNotificationPublisher. NOTIFICATION_ID , 1 ) ;
notificationIntent.putExtra(MyNotificationPublisher. NOTIFICATION , notification) ;
PendingIntent pendingIntent = PendingIntent. getBroadcast ( this, 0 , notificationIntent , PendingIntent. FLAG_UPDATE_CURRENT ) ;
AlarmManager alarmManager = (AlarmManager) getSystemService(Context. ALARM_SERVICE ) ;
assert alarmManager != null;
alarmManager.set(AlarmManager. ELAPSED_REALTIME_WAKEUP , delay , pendingIntent) ;
}
private Notification getNotification (String content) {
NotificationCompat.Builder builder = new NotificationCompat.Builder( this, default_notification_channel_id ) ;
builder.setContentTitle( "Scheduled Notification" ) ;
builder.setContentText(content) ;
builder.setSmallIcon(R.drawable. ic_launcher_foreground ) ;
builder.setAutoCancel( true ) ;
builder.setChannelId( NOTIFICATION_CHANNEL_ID ) ;
return builder.build() ;
}
DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet (DatePicker view , int year , int monthOfYear , int dayOfMonth) {
myCalendar .set(Calendar. YEAR , year) ;
myCalendar .set(Calendar. MONTH , monthOfYear) ;
myCalendar .set(Calendar. DAY_OF_MONTH , dayOfMonth) ;
updateLabel() ;
}
} ;
public void setDate (View view) {
new DatePickerDialog(MainActivity. this, date ,
myCalendar .get(Calendar. YEAR ) ,
myCalendar .get(Calendar. MONTH ) ,
myCalendar .get(Calendar. DAY_OF_MONTH )
).show() ;
}
private void updateLabel () {
String myFormat = "dd/MM/yy" ; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat , Locale. getDefault ()) ;
Date date = myCalendar .getTime() ;
btnDate .setText(sdf.format(date)) ;
scheduleNotification(getNotification( btnDate .getText().toString()) , date.getTime()) ;
}
}
4단계: MyNotificationPublisher 구현
src/MyNotificationPublisher에 다음 코드를 추가합니다. 이 BroadcastReceiver는 AlarmManager가 예약된 시각에 발송한 브로드캐스트를 받아 실제 알림을 화면에 표시하는 역할을 담당합니다.
package app.tutorialspoint.com.notifyme ;
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 static app.tutorialspoint.com.notifyme.MainActivity. NOTIFICATION_CHANNEL_ID ;
public class MyNotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id" ;
public static String NOTIFICATION = "notification" ;
public void onReceive (Context context , Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context. NOTIFICATION_SERVICE ) ;
Notification notification = intent.getParcelableExtra( NOTIFICATION ) ;
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) ;
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel) ;
}
int id = intent.getIntExtra( NOTIFICATION_ID , 0 ) ;
assert notificationManager != null;
notificationManager.notify(id , notification) ;
}
}
5단계: AndroidManifest.xml 설정
AndroidManifest.xml에 다음 코드를 추가합니다. 진동 권한과 함께 BroadcastReceiver를 반드시 등록해야 알림이 정상적으로 동작합니다.
<? 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" />
<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" >
<activity android :name = ".MainActivity" >
<intent-filter>
<action android :name = "android.intent.action.MAIN" />
<category android :name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android :name= ".MyNotificationPublisher" />
</application>
</manifest>
앱 실행 및 결과 확인
이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기를 컴퓨터에 연결했다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하세요. 목록에서 본인의 모바일 기기를 선택하면, 기기 화면에 앱의 기본 화면이 표시됩니다.
날짜를 선택하면 해당 시점에 맞춰 알림이 예약되며, 지정된 시간이 되면 기기 상단에 예약된 알림이 나타나는 것을 확인할 수 있습니다.