Android Studio开发:如何添加自定义日期时间的闹钟?及用药提醒APP弹窗功能实现咨询
Hey there! Let's break down your two Android development questions one by one, with practical code snippets to help you implement them smoothly:
Setting a custom date/time alarm involves working with AlarmManager, PendingIntent, and handling Android version-specific requirements. Here's how to do it:
Step 1: Declare Required Permissions
For Android 12 (API 31) and above, you need theSCHEDULE_EXACT_ALARMpermission to set precise alarms. Add these to yourAndroidManifest.xml:<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Optional: Wake device when alarm triggers -->Also, check and request the permission at runtime for API 31+:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager if (!alarmManager.canScheduleExactAlarms()) { startActivity(Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)) } }Step 2: Create a BroadcastReceiver for Alarm Triggers
This component will handle the alarm event (e.g., show a notification). Create a class like:class MedicationAlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Create a notification channel (required for Android 8.0+) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( "MEDICATION_CHANNEL", "Medication Reminders", NotificationManager.IMPORTANCE_HIGH ) notificationManager.createNotificationChannel(channel) } // Build and show the reminder notification val notification = NotificationCompat.Builder(context, "MEDICATION_CHANNEL") .setContentTitle("Time to take your meds!") .setContentText(intent?.getStringExtra("MED_NAME")) .setSmallIcon(R.drawable.ic_medication) .setPriority(NotificationCompat.PRIORITY_HIGH) .build() notificationManager.notify(System.currentTimeMillis().toInt(), notification) } }Register it in your
AndroidManifest.xml:<receiver android:name=".MedicationAlarmReceiver" />Step 3: Set the Alarm with Selected Date/Time
Convert your picked date/time to a timestamp, then useAlarmManagerto schedule the alarm:// Assume you have selected year, month, day, hour, minute from pickers val selectedCalendar = Calendar.getInstance().apply { set(selectedYear, selectedMonth, selectedDay, selectedHour, selectedMinute, 0) set(Calendar.MILLISECOND, 0) } val alarmTimestamp = selectedCalendar.timeInMillis val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val intent = Intent(this, MedicationAlarmReceiver::class.java).apply { putExtra("MED_NAME", "Your Medication") // Pass med details here } val pendingIntent = PendingIntent.getBroadcast( this, System.currentTimeMillis().toInt(), // Unique request code for multiple alarms intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Use version-compatible alarm method when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTimestamp, pendingIntent) } Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTimestamp, pendingIntent) } else -> { alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTimestamp, pendingIntent) } }
For your "SET ALARM" button, we'll use a custom AlertDialog (easier than a raw PopupWindow for this use case) to collect medication details before setting the alarm:
Step 1: Create a Custom Popup Layout
Make an XML filepopup_add_medication.xmlwith fields for medication info:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add Medication Reminder" android:textSize="18sp" android:textStyle="bold"/> <EditText android:id="@+id/et_med_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Medication Name" android:layout_marginTop="8dp"/> <EditText android:id="@+id/et_med_dosage" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Dosage (e.g., 1 tablet)" android:layout_marginTop="8dp"/> <Button android:id="@+id/btn_save_reminder" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Save & Set Alarm" android:layout_marginTop="16dp"/> </LinearLayout>Step 2: Trigger the Popup on Button Click
In your Activity/Fragment, add a click listener to your "SET ALARM" button:btn_set_alarm.setOnClickListener { val popupView = LayoutInflater.from(this).inflate(R.layout.popup_add_medication, null) val etMedName = popupView.findViewById<EditText>(R.id.et_med_name) val etMedDosage = popupView.findViewById<EditText>(R.id.et_med_dosage) val btnSave = popupView.findViewById<Button>(R.id.btn_save_reminder) val dialog = AlertDialog.Builder(this) .setView(popupView) .create() btnSave.setOnClickListener { val medName = etMedName.text.toString().trim() val medDosage = etMedDosage.text.toString().trim() if (medName.isNotEmpty()) { // Save reminder to storage (SharedPreferences/Room) if needed saveReminderToStorage(medName, medDosage, selectedCalendar.timeInMillis) // Set the alarm using the function from question 1 setMedicationAlarm(medName, selectedCalendar.timeInMillis) Toast.makeText(this, "Reminder set successfully!", Toast.LENGTH_SHORT).show() dialog.dismiss() } else { Toast.makeText(this, "Please enter a medication name!", Toast.LENGTH_SHORT).show() } } dialog.show() }Optional: Save Reminders to Storage
UseSharedPreferencesto store reminders for later reference:private fun saveReminderToStorage(name: String, dosage: String, timestamp: Long) { val prefs = getSharedPreferences("MedReminders", Context.MODE_PRIVATE) val editor = prefs.edit() val uniqueKey = "reminder_${System.currentTimeMillis()}" editor.putString(uniqueKey, "$name|$dosage|$timestamp") editor.apply() }
内容的提问来源于stack exchange,提问作者Mohammed Rabiul Hossain




