revision 4.1.0#6
Conversation
Clarence212
commented
Mar 11, 2026
- Improved UI
- Fixed Bugs
- Bypassed Android Power Optimizations
|
@copilot review |
|
@Clarence212 I've opened a new pull request, #7, to work on those changes. Once the pull request is ready, I'll request review from you. |
There was a problem hiding this comment.
Pull request overview
This PR updates the Android alarm app for the “4.1” release by rebranding the app name, refreshing parts of the UI, and adding new runtime/OS-level behaviors intended to improve alarm reliability (notification permission, exact alarms, and battery optimization handling).
Changes:
- Renames the project/app display name to GisingApp and bumps version to 4.1 (
versionCode41). - Updates UI resources/layouts (main screen header sizing, time/date presentation, switch tinting, new dark palette resources).
- Changes alarm runtime behavior: adds permission prompts + battery optimization requests, schedules alarms via
AlarmManager.setAlarmClock, and adds “keep in foreground” logic inAlarmRingActivity.
Reviewed changes
Copilot reviewed 16 out of 20 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| settings.gradle.kts | Renames Gradle root project. |
| app/src/main/res/values/strings.xml | Renames app_name to GisingApp. |
| app/src/main/res/values/colors.xml | Adds dark-mode color palette resources. |
| app/src/main/res/layout/item_alarm.xml | Moves switch tinting to ColorStateList resources. |
| app/src/main/res/layout/activity_main.xml | Adjusts header sizing and time/date layout/constraints. |
| app/src/main/res/drawable/ic_sun.xml | Adds a new vector drawable. |
| app/src/main/res/color/switch_track_color.xml | Adds track tint selector for switch. |
| app/src/main/res/color/switch_thumb_color.xml | Adds thumb tint selector for switch. |
| app/src/main/java/com/example/gisingv3/MainActivity.java | Adds permission/battery-optimization prompts; switches alarm scheduling to setAlarmClock; tweaks time format. |
| app/src/main/java/com/example/gisingv3/AlarmRingActivity.java | Blocks back navigation via dispatcher callback; adds self-relaunch behavior when backgrounded; tweaks formatting. |
| app/src/main/java/com/example/gisingv3/AlarmReceiver.java | Adds a partial wake lock; adjusts intent flags; minor refactors. |
| app/src/main/java/com/example/gisingv3/Alarm.java | Changes time formatting to remove leading zero hour. |
| app/src/main/java/com/example/gisingv3/AddAlarmActivity.java | Changes time formatting to remove leading zero hour. |
| app/src/main/AndroidManifest.xml | Adds ignore-battery-optimization permission and HTC quickboot action. |
| app/release/output-metadata.json | Updates version metadata and references generated baseline profile artifacts. |
| app/release/baselineProfiles/0/app-release.dm | Adds generated baseline profile artifact. |
| app/release/baselineProfiles/1/app-release.dm | Adds generated baseline profile artifact. |
| app/build.gradle.kts | Bumps version and simplifies compileSdk definition; removes a comment. |
| .idea/deploymentTargetSelector.xml | Updates IDE deployment target selection (now includes local absolute paths). |
| .idea/.name | Renames IDE project name. |
Files not reviewed (2)
- .idea/.name: Language not supported
- .idea/deploymentTargetSelector.xml: Language not supported
Comments suppressed due to low confidence (1)
app/release/output-metadata.json:26
app/release/output-metadata.jsonand the referenced baseline profile artifacts are Gradle build outputs (they point toapp-release.apkand generated.dmfiles). Committing these artifacts will bloat the repo and easily get out of sync with actual releases. Consider deletingapp/release/**from source control and updating.gitignoreto exclude it (or only commit the canonical baseline profile sources, not generated outputs).
"versionCode": 41,
"versionName": "4.1",
"outputFile": "app-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-release.dm"
]
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <DropdownSelection timestamp="2026-03-11T11:22:48.189390300Z"> | ||
| <Target type="DEFAULT_BOOT"> | ||
| <handle> | ||
| <DeviceId pluginId="PhysicalDevice" identifier="serial=U4YYD22315502349" /> | ||
| <DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\maila\.android\avd\Medium_Phone.avd" /> | ||
| </handle> |
There was a problem hiding this comment.
This file contains machine-specific absolute paths and user names (e.g., C:\Users\...) which will churn in PRs and can leak developer-identifying info. Consider removing deploymentTargetSelector.xml from version control and adding it to .gitignore (or rewriting it to avoid absolute paths).
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| long triggerTime = getNextTriggerTime(alarm); | ||
|
|
||
| Intent showIntent = new Intent(this, MainActivity.class); | ||
| PendingIntent pShowIntent = PendingIntent.getActivity(this, 0, showIntent, PendingIntent.FLAG_IMMUTABLE); |
There was a problem hiding this comment.
PendingIntent pShowIntent uses a constant requestCode (0). With multiple alarms, this PendingIntent can be reused/overwritten across alarms, which can make the system’s “next alarm” UI point to the wrong instance. Use a unique requestCode (e.g., alarm.getId()) and/or make the intent unique (data/extras + FLAG_UPDATE_CURRENT).
| PendingIntent pShowIntent = PendingIntent.getActivity(this, 0, showIntent, PendingIntent.FLAG_IMMUTABLE); | |
| showIntent.putExtra("alarm_id", alarm.getId()); | |
| showIntent.setData(Uri.parse("alarm://" + alarm.getId() + "/show")); | |
| PendingIntent pShowIntent = PendingIntent.getActivity( | |
| this, | |
| alarm.getId(), | |
| showIntent, | |
| PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE | |
| ); |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
| PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); | ||
| if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) { | ||
| @SuppressLint("BatteryLife") | ||
| Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); | ||
| intent.setData(Uri.parse("package:" + getPackageName())); | ||
| try { | ||
| startActivity(intent); | ||
| } catch (Exception e) { | ||
| Intent fallback = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS); | ||
| startActivity(fallback); | ||
| } | ||
| } |
There was a problem hiding this comment.
Requesting the battery-optimization exemption in onCreate() will prompt users on every cold start until granted, even if they haven’t set any alarms yet. Consider gating this behind a user action (e.g., after enabling an alarm), persisting a “dismissed/asked” flag, and/or showing an explanation UI before launching the settings intent.
| // Use a WakeLock to ensure the CPU stays awake while we process the alarm | ||
| PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); | ||
| PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "GisingApp:AlarmWakeLock"); | ||
| wakeLock.acquire(10000); // Hold for 10 seconds | ||
|
|
There was a problem hiding this comment.
PowerManager can be null here, and the WakeLock is never released. This can crash (NullPointerException) and/or keep the CPU awake longer than necessary if later code throws. Add a null-check for powerManager, and wrap the receiver work in try/finally to release() the wake lock (still keeping a timeout as a safety net).
| for (int i = 0; i < 7; i++) { | ||
| int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); | ||
| int dayIndex = dayOfWeek - 1; | ||
|
|
||
| if (days[dayIndex]) { | ||
| if (alarm.getDaysSelected()[dayIndex]) { | ||
| if (alarmManager != null) { |
There was a problem hiding this comment.
This loop calls alarm.getDaysSelected() on every iteration. If daysSelected is null, getDaysSelected() allocates a new boolean[7] each time, and even when non-null it’s repeated work. Store the result in a local boolean[] days = alarm.getDaysSelected() before the loop and index into that array.
|
@Clarence212 I've opened a new pull request, #8, to work on those changes. Once the pull request is ready, I'll request review from you. |