Activity_main.
xml :
<?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="match_parent"
android:orientation="vertical"
android:background="#F5F5F5">
<!-- Current Time Display Card -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:elevation="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/colorAccent"
android:padding="16dp">
<TextView
android:id="@+id/selectedTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="72sp"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:fontFamily="sans-serif-light"
android:text="00:00"/>
<TextView
android:id="@+id/ampmDisplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="AM PM"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:alpha="0.9"
android:fontFamily="sans-serif-medium"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Time Picker in Card -->
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="16dp"
android:elevation="8dp">
<TimePicker
android:id="@+id/timePicker"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:timePickerMode="clock"
android:theme="@style/TimePickerTheme"/>
</androidx.cardview.widget.CardView>
<!-- Control Buttons Container -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<ToggleButton
android:id="@+id/toggleButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@drawable/rounded_button"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
android:fontFamily="sans-serif-medium"
android:textOff="SET ALARM"
android:textOn="ALARM ON"
android:onClick="OnToggleClicked"/>
<TextView
android:id="@+id/alarmStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="12dp"
android:textSize="16sp"
android:fontFamily="sans-serif"
android:textColor="@color/colorPrimary"/>
</LinearLayout>
</LinearLayout>
AlarmReceiver.java :
package com.example.alarmclock;
import static android.os.Build.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.PowerManager;
import android.os.Vibrator;
import android.os.VibrationEffect;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import android.app.PendingIntent;
import android.app.AlarmManager; // Add this
import android.widget.Toast; // Add this
import java.util.Calendar; // Add this
public class AlarmReceiver extends BroadcastReceiver {
private static final String STOP_ACTION = "STOP_ALARM";
private static final String SNOOZE_ACTION = "SNOOZE_ALARM";
private MediaPlayer mediaPlayer;
@RequiresApi(api = VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager)
context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "AlarmClock::AlarmWakeLock");
wakeLock.acquire(60000);
// Setup and play alarm sound
try {
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(context, alarmUri);
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mediaPlayer.setAudioAttributes(attributes);
mediaPlayer.setLooping(true);
mediaPlayer.prepare();
mediaPlayer.start();
// Vibrate
Vibrator vibrator = (Vibrator)
context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator.hasVibrator()) {
vibrator.vibrate(VibrationEffect.createWaveform(new long[]{0, 1000, 1000}, 0));
}
// Show notification
if (STOP_ACTION.equals(intent.getAction())) {
stopAlarm(context);
return;
} else if (SNOOZE_ACTION.equals(intent.getAction())) {
snoozeAlarm(context);
return;
}
// Create notification channel
NotificationManager notificationManager =
(NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"alarm_channel", "Alarm", NotificationManager.IMPORTANCE_HIGH);
channel.setSound(null, null);
channel.setImportance(NotificationManager.IMPORTANCE_HIGH);
channel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
channel.enableVibration(true);
notificationManager.createNotificationChannel(channel);
// Create Stop Intent
Intent stopIntent = new Intent(context, AlarmReceiver.class);
stopIntent.setAction(STOP_ACTION);
PendingIntent stopPendingIntent = PendingIntent.getBroadcast(
context, 0, stopIntent,
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_IMMUTABLE);
// Create Snooze Intent
Intent snoozeIntent = new Intent(context, AlarmReceiver.class);
snoozeIntent.setAction(SNOOZE_ACTION);
PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(
context, 1, snoozeIntent,
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_IMMUTABLE);
// Create full screen intent
Intent fullScreenIntent = new Intent(context, MainActivity.class);
fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(
context, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_IMMUTABLE);
// Build notification with actions
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,
"alarm_channel")
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
.setContentTitle("Alarm!")
.setContentText("Time to wake up!")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(false)
.setOngoing(true)
.setSound(null)
.setFullScreenIntent(fullScreenPendingIntent, true)
.setContentIntent(fullScreenPendingIntent)
.addAction(new NotificationCompat.Action(
android.R.drawable.ic_menu_close_clear_cancel,
"Stop",
stopPendingIntent))
.addAction(new NotificationCompat.Action(
android.R.drawable.ic_popup_reminder,
"Snooze 5min",
snoozePendingIntent));
notificationManager.notify(1, builder.build());
} catch (Exception e) {
e.printStackTrace();
} finally {
wakeLock.release();
}
}
private void stopAlarm(Context context) {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
NotificationManager notificationManager =
(NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1);
}
private void snoozeAlarm(Context context) {
// Stop current alarm
stopAlarm(context);
// Set new alarm for 5 minutes later
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 5);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 2, intent,
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_IMMUTABLE);
AlarmManager alarmManager = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setAlarmClock(
new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), pendingIntent),
pendingIntent
);
Toast.makeText(context, "Alarm snoozed for 5 minutes",
Toast.LENGTH_SHORT).show();
}
}
MainActivity.java
package com.example.alarmclock;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView; // Add this import
import android.widget.TimePicker;
import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
TimePicker alarmTimePicker;
TextView selectedTime, ampmDisplay, alarmStatus;
PendingIntent pendingIntent;
AlarmManager alarmManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmTimePicker = findViewById(R.id.timePicker);
selectedTime = findViewById(R.id.selectedTime);
ampmDisplay = findViewById(R.id.ampmDisplay);
alarmStatus = findViewById(R.id.alarmStatus);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// Update time display when time is changed
alarmTimePicker.setOnTimeChangedListener((view, hourOfDay, minute) -> {
String timeStr = String.format("%02d:%02d", hourOfDay, minute);
selectedTime.setText(timeStr);
ampmDisplay.setText(hourOfDay >= 12 ? "PM" : "AM");
});
}
public void OnToggleClicked(View view) {
if (((ToggleButton) view).isChecked()) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_IMMUTABLE
);
long time = calendar.getTimeInMillis();
if (System.currentTimeMillis() > time) {
time = time + (1000 * 60 * 60 * 24);
}
alarmManager.setAlarmClock(
new AlarmManager.AlarmClockInfo(time, pendingIntent),
pendingIntent
);
String alarmTime = String.format("%02d:%02d",
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE));
alarmStatus.setText("Alarm set for " + alarmTime);
Toast.makeText(this, "ALARM SET FOR " + alarmTime,
Toast.LENGTH_SHORT).show();
} else {
alarmManager.cancel(pendingIntent);
alarmStatus.setText("");
Toast.makeText(this, "ALARM CANCELLED", Toast.LENGTH_SHORT).show();
}
}
}
AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Essential Permissions for Alarm Clock -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission
android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
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"
android:exported="true"
android:screenOrientation="portrait"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Broadcast Receiver for Alarm -->
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="false" />
</application>
</manifest>