Giới thiệu
Ví dụ này minh họa cách tạo một báo thức (alarm) kích hoạt tại một ngày và giờ cụ thể trên Android, sử dụng AlarmManager, TimePickerDialog và BroadcastReceiver để hiển thị thông báo.
Bước 1: Tạo dự án mới
Tạo dự án trong Android Studio: File → New Project, điền thông tin cần thiết.
Bước 2: Giao diện (res/layout/activity_main.xml)
Layout đơn giản, chỉ chứa một LinearLayout gốc. Giao diện chọn giờ sẽ hiển thị qua DialogFragment.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
</LinearLayout>
Bước 3: MainActivity - Xử lý chọn giờ và đặt alarm
Activity implement TimePickerDialog.OnTimeSetListener để nhận giờ người dùng chọn, sau đó lập lịch alarm qua AlarmManager.setExact().
package app.com.sample;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TimePicker;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Objects;
public class MainActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {
String timeText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DialogFragment timePicker = new TimePickerFragment();
timePicker.show(getSupportFragmentManager(), "time picker");
}
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
updateTimeText(c);
startAlarm(c);
}
private void updateTimeText(Calendar c) {
timeText = "Báo thức đã đặt lúc: ";
timeText += DateFormat.getTimeInstance(DateFormat.SHORT).format(c.getTime());
}
private void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, NotificationPublisher.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_IMMUTABLE);
if (c.before(Calendar.getInstance())) c.add(Calendar.DATE, 1);
Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
}
Bước 4: BroadcastReceiver - NotificationPublisher
Nhận intent từ AlarmManager và hiển thị thông báo (Notification) qua NotificationHelper.
package app.com.sample;
import android.app.Notification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import androidx.core.app.NotificationCompat;
public class NotificationPublisher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(1, nb.build());
Notification notification = nb.build();
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_SOUND;
}
}
Bước 5: NotificationHelper - Quản lý kênh thông báo (Android O+)
Tạo NotificationChannel cho Android 8.0 (API 26) trở lên, cấu hình độ quan trọng cao, icon, tiêu đề, nội dung.
package app.com.sample;
import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Build;
import androidx.core.app.NotificationCompat;
class NotificationHelper extends ContextWrapper {
public static final String channelID = "channelID";
public static final String channelName = "Kênh Báo Thức";
private NotificationManager notificationManager;
public NotificationHelper(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) createChannel();
}
@TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
public NotificationManager getManager() {
if (notificationManager == null) notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
return notificationManager;
}
public NotificationCompat.Builder getChannelNotification() {
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setContentTitle("Báo Thức Đã Kích Hoạt")
.setContentText("Báo thức của bạn đang reo!")
.setSmallIcon(R.drawable.ic_alarm);
}
}
Bước 6: TimePickerFragment - Dialog chọn giờ
package app.com.sample;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.text.format.DateFormat;
import java.util.Calendar;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
public class TimePickerFragment extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(), hour, minute, DateFormat.is24HourFormat(getActivity()));
}
}
Bước 7: Manifest - Đăng ký Receiver
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="app.com.sample">
<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=".NotificationPublisher"></receiver>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, chạy app. Dialog chọn giờ hiện ra, sau khi chọn, alarm sẽ được đặt. Khi đến giờ, thông báo sẽ hiện ra ngay cả khi app đã đóng.