Skip to content

Commit

Permalink
[Feature] Add allowAlarmOverlap parameter (#303)
Browse files Browse the repository at this point in the history
* Add allowAlarmOverlap param

* Fix android check if alarm is already ringing
  • Loading branch information
gdelataillade authored Dec 13, 2024
1 parent 8491f1f commit 9a2f390
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class AlarmService : Service() {
}

// Check if an alarm is already ringing
if (ringingAlarmIds.isNotEmpty() && action != "STOP_ALARM") {
if (!alarmSettings.allowAlarmOverlap && ringingAlarmIds.isNotEmpty() && action != "STOP_ALARM") {
Log.d("AlarmService", "An alarm is already ringing. Ignoring new alarm with id: $id")
unsaveAlarm(id)
return START_NOT_STICKY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ data class AlarmSettingsWire (
val loopAudio: Boolean,
val vibrate: Boolean,
val warningNotificationOnKill: Boolean,
val androidFullScreenIntent: Boolean
val androidFullScreenIntent: Boolean,
val allowAlarmOverlap: Boolean
)
{
companion object {
Expand All @@ -97,7 +98,8 @@ data class AlarmSettingsWire (
val vibrate = pigeonVar_list[6] as Boolean
val warningNotificationOnKill = pigeonVar_list[7] as Boolean
val androidFullScreenIntent = pigeonVar_list[8] as Boolean
return AlarmSettingsWire(id, millisecondsSinceEpoch, assetAudioPath, volumeSettings, notificationSettings, loopAudio, vibrate, warningNotificationOnKill, androidFullScreenIntent)
val allowAlarmOverlap = pigeonVar_list[9] as Boolean
return AlarmSettingsWire(id, millisecondsSinceEpoch, assetAudioPath, volumeSettings, notificationSettings, loopAudio, vibrate, warningNotificationOnKill, androidFullScreenIntent, allowAlarmOverlap)
}
}
fun toList(): List<Any?> {
Expand All @@ -111,6 +113,7 @@ data class AlarmSettingsWire (
vibrate,
warningNotificationOnKill,
androidFullScreenIntent,
allowAlarmOverlap,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ data class AlarmSettings(
val loopAudio: Boolean,
val vibrate: Boolean,
val warningNotificationOnKill: Boolean,
val androidFullScreenIntent: Boolean
val androidFullScreenIntent: Boolean,
val allowAlarmOverlap: Boolean = false
) {
companion object {
fun fromWire(e: AlarmSettingsWire): AlarmSettings {
Expand All @@ -34,6 +35,7 @@ data class AlarmSettings(
e.vibrate,
e.warningNotificationOnKill,
e.androidFullScreenIntent,
e.allowAlarmOverlap
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = WQ65PJ26MP;
DEVELOPMENT_TEAM = 63LD84R3KS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down Expand Up @@ -514,7 +514,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = WQ65PJ26MP;
DEVELOPMENT_TEAM = 63LD84R3KS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down Expand Up @@ -542,7 +542,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = WQ65PJ26MP;
DEVELOPMENT_TEAM = 63LD84R3KS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down
1 change: 1 addition & 0 deletions example/lib/screens/edit_alarm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class _ExampleAlarmEditScreenState extends State<ExampleAlarmEditScreen> {
assetAudioPath: assetAudio,
warningNotificationOnKill: Platform.isIOS,
volumeSettings: volumeSettings,
allowAlarmOverlap: true,
notificationSettings: NotificationSettings(
title: 'Alarm example',
body: 'Your alarm ($id) is ringing',
Expand Down
8 changes: 4 additions & 4 deletions ios/Classes/api/AlarmApiImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,13 @@ public class AlarmApiImpl: NSObject, AlarmApi {
}

private func handleAlarmAfterDelay(id: Int) {
if self.isAnyAlarmRingingExcept(id: id) {
NSLog("[SwiftAlarmPlugin] Ignoring alarm with id \(id) because another alarm is already ringing.")
self.unsaveAlarm(id: id)
guard let alarm = self.alarms[id], let audioPlayer = alarm.audioPlayer else {
return
}

guard let alarm = self.alarms[id], let audioPlayer = alarm.audioPlayer else {
if !alarm.settings.allowAlarmOverlap && self.isAnyAlarmRingingExcept(id: id) {
NSLog("[SwiftAlarmPlugin] Ignoring alarm with id \(id) because another alarm is already ringing.")
self.unsaveAlarm(id: id)
return
}

Expand Down
6 changes: 5 additions & 1 deletion ios/Classes/generated/FlutterBindings.g.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct AlarmSettingsWire {
var vibrate: Bool
var warningNotificationOnKill: Bool
var androidFullScreenIntent: Bool
var allowAlarmOverlap: Bool


// swift-format-ignore: AlwaysUseLowerCamelCase
Expand All @@ -108,6 +109,7 @@ struct AlarmSettingsWire {
let vibrate = pigeonVar_list[6] as! Bool
let warningNotificationOnKill = pigeonVar_list[7] as! Bool
let androidFullScreenIntent = pigeonVar_list[8] as! Bool
let allowAlarmOverlap = pigeonVar_list[9] as! Bool

return AlarmSettingsWire(
id: id,
Expand All @@ -118,7 +120,8 @@ struct AlarmSettingsWire {
loopAudio: loopAudio,
vibrate: vibrate,
warningNotificationOnKill: warningNotificationOnKill,
androidFullScreenIntent: androidFullScreenIntent
androidFullScreenIntent: androidFullScreenIntent,
allowAlarmOverlap: allowAlarmOverlap
)
}
func toList() -> [Any?] {
Expand All @@ -132,6 +135,7 @@ struct AlarmSettingsWire {
vibrate,
warningNotificationOnKill,
androidFullScreenIntent,
allowAlarmOverlap,
]
}
}
Expand Down
54 changes: 50 additions & 4 deletions ios/Classes/models/AlarmSettings.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

struct AlarmSettings: Codable {
let id: Int
let dateTime: Date
Expand All @@ -10,6 +8,53 @@ struct AlarmSettings: Codable {
let vibrate: Bool
let warningNotificationOnKill: Bool
let androidFullScreenIntent: Bool
let allowAlarmOverlap: Bool

enum CodingKeys: String, CodingKey {
case id, dateTime, assetAudioPath, volumeSettings, notificationSettings,
loopAudio, vibrate, warningNotificationOnKill, androidFullScreenIntent,
allowAlarmOverlap
}

// Custom initializer to handle missing keys
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
dateTime = try container.decode(Date.self, forKey: .dateTime)
assetAudioPath = try container.decode(String.self, forKey: .assetAudioPath)
volumeSettings = try container.decode(VolumeSettings.self, forKey: .volumeSettings)
notificationSettings = try container.decode(NotificationSettings.self, forKey: .notificationSettings)
loopAudio = try container.decode(Bool.self, forKey: .loopAudio)
vibrate = try container.decode(Bool.self, forKey: .vibrate)
warningNotificationOnKill = try container.decode(Bool.self, forKey: .warningNotificationOnKill)
androidFullScreenIntent = try container.decode(Bool.self, forKey: .androidFullScreenIntent)
allowAlarmOverlap = try container.decodeIfPresent(Bool.self, forKey: .allowAlarmOverlap) ?? false
}

// Memberwise initializer
init(
id: Int,
dateTime: Date,
assetAudioPath: String,
volumeSettings: VolumeSettings,
notificationSettings: NotificationSettings,
loopAudio: Bool,
vibrate: Bool,
warningNotificationOnKill: Bool,
androidFullScreenIntent: Bool,
allowAlarmOverlap: Bool
) {
self.id = id
self.dateTime = dateTime
self.assetAudioPath = assetAudioPath
self.volumeSettings = volumeSettings
self.notificationSettings = notificationSettings
self.loopAudio = loopAudio
self.vibrate = vibrate
self.warningNotificationOnKill = warningNotificationOnKill
self.androidFullScreenIntent = androidFullScreenIntent
self.allowAlarmOverlap = allowAlarmOverlap
}

static func from(wire: AlarmSettingsWire) -> AlarmSettings {
return AlarmSettings(
Expand All @@ -21,7 +66,8 @@ struct AlarmSettings: Codable {
loopAudio: wire.loopAudio,
vibrate: wire.vibrate,
warningNotificationOnKill: wire.warningNotificationOnKill,
androidFullScreenIntent: wire.androidFullScreenIntent
androidFullScreenIntent: wire.androidFullScreenIntent,
allowAlarmOverlap: wire.allowAlarmOverlap
)
}
}
}
12 changes: 11 additions & 1 deletion lib/model/alarm_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AlarmSettings {
this.vibrate = true,
this.warningNotificationOnKill = true,
this.androidFullScreenIntent = true,
this.allowAlarmOverlap = false,
});

/// Constructs an `AlarmSettings` instance from the given JSON data.
Expand All @@ -38,7 +39,8 @@ class AlarmSettings {
loopAudio = wire.loopAudio,
vibrate = wire.vibrate,
warningNotificationOnKill = wire.warningNotificationOnKill,
androidFullScreenIntent = wire.androidFullScreenIntent;
androidFullScreenIntent = wire.androidFullScreenIntent,
allowAlarmOverlap = false;

/// Unique identifier assiocated with the alarm. Cannot be 0 or -1;
final int id;
Expand Down Expand Up @@ -103,6 +105,11 @@ class AlarmSettings {
/// package.
final bool androidFullScreenIntent;

/// Whether the alarm should ring if another alarm is already ringing.
///
/// Defaults to `false`.
final bool allowAlarmOverlap;

/// Converts the `AlarmSettings` instance to a JSON object.
Map<String, dynamic> toJson() => _$AlarmSettingsToJson(this);

Expand All @@ -117,6 +124,7 @@ class AlarmSettings {
vibrate: vibrate,
warningNotificationOnKill: warningNotificationOnKill,
androidFullScreenIntent: androidFullScreenIntent,
allowAlarmOverlap: allowAlarmOverlap,
);

/// Creates a copy of `AlarmSettings` but with the given fields replaced with
Expand All @@ -138,6 +146,7 @@ class AlarmSettings {
String? notificationBody,
bool? warningNotificationOnKill,
bool? androidFullScreenIntent,
bool? allowAlarmOverlap,
}) {
return AlarmSettings(
id: id ?? this.id,
Expand All @@ -151,6 +160,7 @@ class AlarmSettings {
warningNotificationOnKill ?? this.warningNotificationOnKill,
androidFullScreenIntent:
androidFullScreenIntent ?? this.androidFullScreenIntent,
allowAlarmOverlap: allowAlarmOverlap ?? this.allowAlarmOverlap,
);
}
}
5 changes: 5 additions & 0 deletions lib/src/generated/platform_bindings.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class AlarmSettingsWire {
this.vibrate = true,
this.warningNotificationOnKill = true,
this.androidFullScreenIntent = true,
this.allowAlarmOverlap = false,
});

int id;
Expand All @@ -77,6 +78,8 @@ class AlarmSettingsWire {

bool androidFullScreenIntent;

bool allowAlarmOverlap;

Object encode() {
return <Object?>[
id,
Expand All @@ -88,6 +91,7 @@ class AlarmSettingsWire {
vibrate,
warningNotificationOnKill,
androidFullScreenIntent,
allowAlarmOverlap,
];
}

Expand All @@ -103,6 +107,7 @@ class AlarmSettingsWire {
vibrate: result[6]! as bool,
warningNotificationOnKill: result[7]! as bool,
androidFullScreenIntent: result[8]! as bool,
allowAlarmOverlap: result[9]! as bool,
);
}
}
Expand Down
2 changes: 2 additions & 0 deletions pigeons/alarm_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AlarmSettingsWire {
this.vibrate = true,
this.warningNotificationOnKill = true,
this.androidFullScreenIntent = true,
this.allowAlarmOverlap = false,
});

final int id;
Expand All @@ -37,6 +38,7 @@ class AlarmSettingsWire {
final bool vibrate;
final bool warningNotificationOnKill;
final bool androidFullScreenIntent;
final bool allowAlarmOverlap;
}

class VolumeSettingsWire {
Expand Down

0 comments on commit 9a2f390

Please sign in to comment.