react-native-alarmageddon 1.1.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +169 -187
- package/android/build/.transforms/33d69af0aa8d226a34981fd71aab63e2/results.bin +1 -0
- package/android/build/.transforms/33d69af0aa8d226a34981fd71aab63e2/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/4aeb440f8cdf777de34ab1099140d239/results.bin +1 -0
- package/android/build/.transforms/4aeb440f8cdf777de34ab1099140d239/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/com/rnalarmmodule/BuildConfig.java +10 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +41 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +1 -0
- package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/raw_alarm_default.wav.flat +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/rnalarmmodule/BuildConfig.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +3 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +68 -0
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +41 -0
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
- package/android/build/intermediates/packaged_res/debug/packageDebugResources/raw/alarm_default.wav +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +2 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +71 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-alarmageddon_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmPackage.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/AlarmReceiver.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/rnalarmmodule/BootReceiver.class +0 -0
- package/android/build.gradle +11 -21
- package/android/src/main/AndroidManifest.xml +16 -35
- package/android/src/main/java/com/rnalarmmodule/AlarmModule.kt +163 -387
- package/android/src/main/java/com/rnalarmmodule/AlarmPackage.kt +0 -1
- package/android/src/main/java/com/rnalarmmodule/AlarmReceiver.kt +300 -129
- package/android/src/main/java/com/rnalarmmodule/BootReceiver.kt +66 -124
- package/android/src/main/res/raw/alarm_default.wav +0 -0
- package/ios/{RNAlarmModule.m → AlarmModule.m} +9 -20
- package/ios/AlarmModule.swift +241 -36
- package/ios/RNAlarmModule-Bridging-Header.h +5 -1
- package/lib/index.d.ts +51 -85
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +60 -120
- package/lib/index.js.map +1 -1
- package/package.json +14 -23
- package/react-native-alarmageddon.podspec +10 -8
- package/react-native.config.js +3 -1
- package/src/index.ts +98 -201
- package/android/gradle.properties +0 -13
- package/android/src/main/java/com/rnalarmmodule/AlarmActivity.kt +0 -79
- package/android/src/main/java/com/rnalarmmodule/AlarmService.kt +0 -290
- package/android/src/main/res/raw/README.md +0 -36
|
@@ -1,485 +1,261 @@
|
|
|
1
1
|
package com.rnalarmmodule
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.*
|
|
3
4
|
import android.app.AlarmManager
|
|
4
5
|
import android.app.PendingIntent
|
|
5
6
|
import android.content.Context
|
|
6
7
|
import android.content.Intent
|
|
7
|
-
import android.content.SharedPreferences
|
|
8
8
|
import android.os.Build
|
|
9
|
-
import
|
|
9
|
+
import java.text.SimpleDateFormat
|
|
10
|
+
import java.util.*
|
|
10
11
|
import android.util.Log
|
|
11
|
-
import com.facebook.react.bridge.*
|
|
12
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
13
|
-
import org.json.JSONArray
|
|
14
12
|
import org.json.JSONObject
|
|
13
|
+
import android.content.pm.PackageManager
|
|
15
14
|
import java.lang.ref.WeakReference
|
|
16
|
-
import java.text.SimpleDateFormat
|
|
17
|
-
import java.util.*
|
|
18
15
|
|
|
19
16
|
class AlarmModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
20
17
|
|
|
21
18
|
companion object {
|
|
22
19
|
private const val TAG = "AlarmModule"
|
|
23
|
-
private const val
|
|
24
|
-
private const val ALARMS_KEY = "alarms"
|
|
20
|
+
private const val PREFS = "rn_alarm_module_alarms"
|
|
25
21
|
private const val DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"
|
|
26
|
-
private const val ACTIVE_ALARM_KEY = "active_alarm_id"
|
|
27
22
|
|
|
28
|
-
// Weak reference to avoid memory leaks
|
|
23
|
+
// Weak reference to avoid memory leaks - used by AlarmReceiver to emit events
|
|
29
24
|
private var reactContextRef: WeakReference<ReactApplicationContext>? = null
|
|
30
25
|
|
|
31
26
|
fun getReactContext(): ReactApplicationContext? = reactContextRef?.get()
|
|
32
|
-
|
|
33
|
-
fun emitActiveAlarmId(id: String?) {
|
|
34
|
-
val reactContext = getReactContext()
|
|
35
|
-
if (reactContext != null && reactContext.hasActiveCatalystInstance()) {
|
|
36
|
-
try {
|
|
37
|
-
reactContext
|
|
38
|
-
.getJSModule(RCTDeviceEventEmitter::class.java)
|
|
39
|
-
.emit("activeAlarmId", id)
|
|
40
|
-
} catch (e: Exception) {
|
|
41
|
-
Log.e(TAG, "Failed to emit activeAlarmId event: ${e.message}")
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
27
|
}
|
|
46
28
|
|
|
47
|
-
private val prefs: SharedPreferences = reactContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
48
|
-
private val dateFormat = SimpleDateFormat(DATE_PATTERN, Locale.getDefault())
|
|
49
|
-
|
|
50
29
|
init {
|
|
30
|
+
// Update the reference whenever the module is instantiated
|
|
51
31
|
reactContextRef = WeakReference(reactContext)
|
|
52
|
-
dateFormat.timeZone = TimeZone.getDefault()
|
|
53
32
|
}
|
|
54
33
|
|
|
55
34
|
override fun getName(): String = "AlarmModule"
|
|
56
35
|
|
|
57
|
-
override fun getConstants(): Map<String, Any> {
|
|
58
|
-
return mapOf(
|
|
59
|
-
"EXACT_ALARM_PERMISSION_REQUIRED" to (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
36
|
@ReactMethod
|
|
64
|
-
fun
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Required for NativeEventEmitter
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@ReactMethod
|
|
74
|
-
fun scheduleAlarm(alarmParams: ReadableMap, promise: Promise) {
|
|
75
|
-
try {
|
|
76
|
-
val id = alarmParams.getString("id") ?: run {
|
|
77
|
-
promise.reject("INVALID_PARAMS", "Alarm ID is required")
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
val datetimeISO = alarmParams.getString("datetimeISO") ?: run {
|
|
81
|
-
promise.reject("INVALID_PARAMS", "datetimeISO is required")
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
val title = alarmParams.getString("title") ?: "Alarm"
|
|
85
|
-
val body = alarmParams.getString("body") ?: ""
|
|
86
|
-
val soundUri = if (alarmParams.hasKey("soundUri")) alarmParams.getString("soundUri") else null
|
|
87
|
-
val vibrate = if (alarmParams.hasKey("vibrate")) alarmParams.getBoolean("vibrate") else true
|
|
88
|
-
val snoozeMinutes = if (alarmParams.hasKey("snoozeMinutes")) alarmParams.getInt("snoozeMinutes") else 5
|
|
89
|
-
val autoStopSeconds = if (alarmParams.hasKey("autoStopSeconds")) alarmParams.getInt("autoStopSeconds") else 60
|
|
90
|
-
|
|
91
|
-
val triggerTime = parseDateTime(datetimeISO)
|
|
92
|
-
if (triggerTime == null) {
|
|
93
|
-
promise.reject("INVALID_DATE", "Could not parse datetimeISO: $datetimeISO")
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Store alarm in SharedPreferences
|
|
98
|
-
val alarm = JSONObject().apply {
|
|
99
|
-
put("id", id)
|
|
100
|
-
put("datetimeISO", datetimeISO)
|
|
101
|
-
put("triggerTime", triggerTime)
|
|
102
|
-
put("title", title)
|
|
103
|
-
put("body", body)
|
|
104
|
-
put("soundUri", soundUri ?: "")
|
|
105
|
-
put("vibrate", vibrate)
|
|
106
|
-
put("snoozeMinutes", snoozeMinutes)
|
|
107
|
-
put("autoStopSeconds", autoStopSeconds)
|
|
108
|
-
}
|
|
109
|
-
saveAlarm(alarm)
|
|
110
|
-
|
|
111
|
-
// Schedule the alarm
|
|
112
|
-
scheduleExactAlarm(id, triggerTime, title, body, soundUri, vibrate, snoozeMinutes, autoStopSeconds)
|
|
113
|
-
|
|
114
|
-
Log.d(TAG, "Alarm scheduled: id=$id, triggerTime=$triggerTime")
|
|
37
|
+
fun getCurrentAlarmPlaying(promise: Promise) {
|
|
38
|
+
if (AlarmReceiver.activeAlarmId != null) {
|
|
39
|
+
val map = Arguments.createMap()
|
|
40
|
+
map.putString("activeAlarmId", AlarmReceiver.activeAlarmId)
|
|
41
|
+
promise.resolve(map)
|
|
42
|
+
} else {
|
|
115
43
|
promise.resolve(null)
|
|
116
|
-
} catch (e: Exception) {
|
|
117
|
-
Log.e(TAG, "Failed to schedule alarm: ${e.message}", e)
|
|
118
|
-
promise.reject("SCHEDULE_ERROR", "Failed to schedule alarm: ${e.message}", e)
|
|
119
44
|
}
|
|
120
45
|
}
|
|
121
46
|
|
|
122
47
|
@ReactMethod
|
|
123
|
-
fun
|
|
48
|
+
fun stopCurrentAlarm(id: String, promise: Promise) {
|
|
124
49
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
50
|
+
val intent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
51
|
+
action = AlarmReceiver.ACTION_STOP
|
|
52
|
+
putExtra("id", id)
|
|
53
|
+
}
|
|
54
|
+
reactApplicationContext.sendBroadcast(intent)
|
|
128
55
|
promise.resolve(null)
|
|
129
56
|
} catch (e: Exception) {
|
|
130
|
-
Log.e(TAG, "Failed to
|
|
131
|
-
promise.reject("
|
|
57
|
+
Log.e(TAG, "Failed to stop alarm: ${e.message}")
|
|
58
|
+
promise.reject("STOP_ERROR", e)
|
|
132
59
|
}
|
|
133
60
|
}
|
|
134
61
|
|
|
135
62
|
@ReactMethod
|
|
136
|
-
fun
|
|
63
|
+
fun snoozeCurrentAlarm(id: String, minutes: Int, promise: Promise) {
|
|
137
64
|
try {
|
|
138
|
-
val
|
|
139
|
-
val
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
65
|
+
val alarm = getAlarm(id) ?: throw Exception("Alarm not found")
|
|
66
|
+
val title = alarm.optString("title", "Alarm")
|
|
67
|
+
val body = alarm.optString("body", "")
|
|
68
|
+
val snoozeEnabled = alarm.optBoolean("snoozeEnabled", true)
|
|
69
|
+
val snoozeInterval = alarm.optInt("snoozeInterval", 5)
|
|
70
|
+
|
|
71
|
+
val intent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
72
|
+
action = AlarmReceiver.ACTION_SNOOZE
|
|
73
|
+
putExtra("id", id)
|
|
74
|
+
putExtra("title", title)
|
|
75
|
+
putExtra("body", "$body (Snoozed)")
|
|
76
|
+
putExtra("snoozeMinutes", minutes)
|
|
77
|
+
putExtra("snoozeEnabled", snoozeEnabled)
|
|
78
|
+
putExtra("snoozeInterval", snoozeInterval)
|
|
152
79
|
}
|
|
153
|
-
|
|
80
|
+
reactApplicationContext.sendBroadcast(intent)
|
|
81
|
+
promise.resolve(null)
|
|
154
82
|
} catch (e: Exception) {
|
|
155
|
-
Log.e(TAG, "Failed to
|
|
156
|
-
promise.reject("
|
|
83
|
+
Log.e(TAG, "Failed to snooze alarm: ${e.message}")
|
|
84
|
+
promise.reject("SNOOZE_ERROR", e)
|
|
157
85
|
}
|
|
158
86
|
}
|
|
159
87
|
|
|
160
88
|
@ReactMethod
|
|
161
89
|
fun requestPermissions(promise: Promise) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
result.putBoolean("granted", canScheduleExact)
|
|
169
|
-
result.putBoolean("exactAlarmGranted", canScheduleExact)
|
|
170
|
-
|
|
171
|
-
if (!canScheduleExact) {
|
|
172
|
-
// Open settings to grant exact alarm permission
|
|
173
|
-
try {
|
|
174
|
-
val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).apply {
|
|
175
|
-
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
176
|
-
}
|
|
177
|
-
reactApplicationContext.startActivity(intent)
|
|
178
|
-
} catch (e: Exception) {
|
|
179
|
-
Log.e(TAG, "Failed to open exact alarm settings: ${e.message}")
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
result.putBoolean("granted", true)
|
|
184
|
-
result.putBoolean("exactAlarmGranted", true)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
promise.resolve(result)
|
|
188
|
-
} catch (e: Exception) {
|
|
189
|
-
Log.e(TAG, "Failed to request permissions: ${e.message}", e)
|
|
190
|
-
promise.reject("PERMISSION_ERROR", "Failed to request permissions: ${e.message}", e)
|
|
191
|
-
}
|
|
90
|
+
val granted = if (Build.VERSION.SDK_INT >= 33) {
|
|
91
|
+
reactApplicationContext.checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
|
92
|
+
} else true
|
|
93
|
+
val map = Arguments.createMap()
|
|
94
|
+
map.putBoolean("granted", granted)
|
|
95
|
+
promise.resolve(map)
|
|
192
96
|
}
|
|
193
97
|
|
|
194
98
|
@ReactMethod
|
|
195
|
-
fun
|
|
99
|
+
fun scheduleAlarm(alarm: ReadableMap, promise: Promise) {
|
|
196
100
|
try {
|
|
197
|
-
val
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
101
|
+
val id = alarm.getString("id") ?: UUID.randomUUID().toString()
|
|
102
|
+
val datetimeISO = alarm.getString("datetimeISO") ?: throw Exception("datetimeISO required")
|
|
103
|
+
val title = alarm.getString("title") ?: "Alarm"
|
|
104
|
+
val body = alarm.getString("body") ?: ""
|
|
105
|
+
val snoozeEnabled = if (alarm.hasKey("snoozeEnabled")) alarm.getBoolean("snoozeEnabled") else true
|
|
106
|
+
val snoozeInterval = if (alarm.hasKey("snoozeInterval")) alarm.getInt("snoozeInterval") else 5
|
|
107
|
+
|
|
108
|
+
val sdf = SimpleDateFormat(DATE_PATTERN, Locale.getDefault())
|
|
109
|
+
val date = sdf.parse(datetimeISO) ?: throw Exception("Invalid date format")
|
|
110
|
+
val triggerAt = date.time
|
|
111
|
+
|
|
112
|
+
val now = System.currentTimeMillis()
|
|
113
|
+
if (triggerAt < now) {
|
|
114
|
+
Log.w(TAG, "scheduleAlarm: trigger time in past ($datetimeISO); scheduling anyway.")
|
|
202
115
|
}
|
|
203
|
-
promise.resolve(result)
|
|
204
|
-
} catch (e: Exception) {
|
|
205
|
-
Log.e(TAG, "Failed to check exact alarm permission: ${e.message}", e)
|
|
206
|
-
promise.reject("PERMISSION_ERROR", "Failed to check permission: ${e.message}", e)
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
116
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
reactApplicationContext.startActivity(intent)
|
|
117
|
+
val alarmManager = reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
118
|
+
val alarmIntent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
119
|
+
putExtra("id", id)
|
|
120
|
+
putExtra("title", title)
|
|
121
|
+
putExtra("body", body)
|
|
122
|
+
putExtra("snoozeEnabled", snoozeEnabled)
|
|
123
|
+
putExtra("snoozeInterval", snoozeInterval)
|
|
218
124
|
}
|
|
219
|
-
promise.resolve(null)
|
|
220
|
-
} catch (e: Exception) {
|
|
221
|
-
Log.e(TAG, "Failed to open exact alarm settings: ${e.message}", e)
|
|
222
|
-
promise.reject("SETTINGS_ERROR", "Failed to open settings: ${e.message}", e)
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
125
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
promise.reject("NOT_FOUND", "Alarm not found: $id")
|
|
232
|
-
return
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
val snoozeTime = System.currentTimeMillis() + (minutes * 60 * 1000L)
|
|
236
|
-
val newDatetimeISO = dateFormat.format(Date(snoozeTime))
|
|
237
|
-
|
|
238
|
-
// Update alarm with new time
|
|
239
|
-
alarm.put("datetimeISO", newDatetimeISO)
|
|
240
|
-
alarm.put("triggerTime", snoozeTime)
|
|
241
|
-
updateAlarm(alarm)
|
|
242
|
-
|
|
243
|
-
// Reschedule
|
|
244
|
-
scheduleExactAlarm(
|
|
245
|
-
id,
|
|
246
|
-
snoozeTime,
|
|
247
|
-
alarm.optString("title", "Alarm"),
|
|
248
|
-
alarm.optString("body", ""),
|
|
249
|
-
alarm.optString("soundUri", null),
|
|
250
|
-
alarm.optBoolean("vibrate", true),
|
|
251
|
-
alarm.optInt("snoozeMinutes", 5),
|
|
252
|
-
alarm.optInt("autoStopSeconds", 60)
|
|
126
|
+
val pendingIntent = PendingIntent.getBroadcast(
|
|
127
|
+
reactApplicationContext,
|
|
128
|
+
id.hashCode(),
|
|
129
|
+
alarmIntent,
|
|
130
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
253
131
|
)
|
|
254
132
|
|
|
255
|
-
|
|
133
|
+
// Use exact alarm scheduling
|
|
134
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
135
|
+
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
|
|
136
|
+
} else {
|
|
137
|
+
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
saveAlarm(id, datetimeISO, title, body, snoozeEnabled, snoozeInterval)
|
|
141
|
+
Log.d(TAG, "Scheduled alarm id=$id at=$datetimeISO")
|
|
256
142
|
promise.resolve(null)
|
|
257
143
|
} catch (e: Exception) {
|
|
258
|
-
Log.e(TAG, "Failed to
|
|
259
|
-
promise.reject("
|
|
144
|
+
Log.e(TAG, "Failed to schedule alarm: ${e.message}")
|
|
145
|
+
promise.reject("SCHEDULE_ERROR", e)
|
|
260
146
|
}
|
|
261
147
|
}
|
|
262
148
|
|
|
263
149
|
@ReactMethod
|
|
264
|
-
fun
|
|
150
|
+
fun cancelAlarm(id: String, promise: Promise) {
|
|
265
151
|
try {
|
|
266
|
-
|
|
267
|
-
val
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
Log.d(TAG, "Alarm stopped: id=$id")
|
|
152
|
+
val intent = Intent(reactApplicationContext, AlarmReceiver::class.java)
|
|
153
|
+
val pi = PendingIntent.getBroadcast(
|
|
154
|
+
reactApplicationContext,
|
|
155
|
+
id.hashCode(),
|
|
156
|
+
intent,
|
|
157
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
158
|
+
)
|
|
159
|
+
val am = reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
160
|
+
am.cancel(pi)
|
|
161
|
+
removeAlarm(id)
|
|
162
|
+
Log.d(TAG, "Cancelled alarm id=$id")
|
|
278
163
|
promise.resolve(null)
|
|
279
164
|
} catch (e: Exception) {
|
|
280
|
-
Log.e(TAG, "Failed to
|
|
281
|
-
promise.reject("
|
|
165
|
+
Log.e(TAG, "Failed to cancel alarm: ${e.message}")
|
|
166
|
+
promise.reject("CANCEL_ERROR", e)
|
|
282
167
|
}
|
|
283
168
|
}
|
|
284
169
|
|
|
285
170
|
@ReactMethod
|
|
286
|
-
fun
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
171
|
+
fun listAlarms(promise: Promise) {
|
|
172
|
+
val arr = Arguments.createArray()
|
|
173
|
+
val prefs = reactApplicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
|
174
|
+
val all = prefs.all
|
|
175
|
+
for ((id, rawJson) in all) {
|
|
176
|
+
val jsonStr = rawJson as? String ?: continue
|
|
177
|
+
val obj = try {
|
|
178
|
+
JSONObject(jsonStr)
|
|
179
|
+
} catch (_: Exception) {
|
|
180
|
+
continue
|
|
292
181
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
} catch (e: Exception) {
|
|
302
|
-
Log.e(TAG, "Failed to snooze current alarm: ${e.message}", e)
|
|
303
|
-
promise.reject("SNOOZE_ERROR", "Failed to snooze current alarm: ${e.message}", e)
|
|
182
|
+
val map = Arguments.createMap()
|
|
183
|
+
map.putString("id", id)
|
|
184
|
+
map.putString("datetimeISO", obj.optString("datetimeISO"))
|
|
185
|
+
map.putString("title", obj.optString("title"))
|
|
186
|
+
map.putString("body", obj.optString("body"))
|
|
187
|
+
map.putBoolean("snoozeEnabled", obj.optBoolean("snoozeEnabled", true))
|
|
188
|
+
map.putInt("snoozeInterval", obj.optInt("snoozeInterval", 5))
|
|
189
|
+
arr.pushMap(map)
|
|
304
190
|
}
|
|
191
|
+
promise.resolve(arr)
|
|
305
192
|
}
|
|
306
193
|
|
|
307
194
|
@ReactMethod
|
|
308
|
-
fun
|
|
195
|
+
fun snoozeAlarm(message: String, snoozeMinutes: Int, promise: Promise) {
|
|
309
196
|
try {
|
|
310
|
-
val
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
promise.resolve(result)
|
|
316
|
-
} else {
|
|
317
|
-
promise.resolve(null)
|
|
197
|
+
val id = UUID.randomUUID().toString()
|
|
198
|
+
val alarmIntent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
199
|
+
putExtra("id", id)
|
|
200
|
+
putExtra("title", "Snoozed Alarm")
|
|
201
|
+
putExtra("body", message)
|
|
318
202
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
private fun parseDateTime(datetimeISO: String): Long? {
|
|
326
|
-
return try {
|
|
327
|
-
// Try parsing with timezone info
|
|
328
|
-
val formats = listOf(
|
|
329
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.getDefault()),
|
|
330
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.getDefault()),
|
|
331
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault()),
|
|
332
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()),
|
|
333
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.getDefault()),
|
|
334
|
-
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()),
|
|
335
|
-
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
|
|
203
|
+
val pendingIntent = PendingIntent.getBroadcast(
|
|
204
|
+
reactApplicationContext,
|
|
205
|
+
id.hashCode(),
|
|
206
|
+
alarmIntent,
|
|
207
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
336
208
|
)
|
|
337
|
-
|
|
338
|
-
for (format in formats) {
|
|
339
|
-
try {
|
|
340
|
-
val date = format.parse(datetimeISO)
|
|
341
|
-
if (date != null) {
|
|
342
|
-
return date.time
|
|
343
|
-
}
|
|
344
|
-
} catch (e: Exception) {
|
|
345
|
-
// Try next format
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
null
|
|
349
|
-
} catch (e: Exception) {
|
|
350
|
-
Log.e(TAG, "Failed to parse date: $datetimeISO", e)
|
|
351
|
-
null
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
private fun scheduleExactAlarm(
|
|
356
|
-
id: String,
|
|
357
|
-
triggerTimeMillis: Long,
|
|
358
|
-
title: String,
|
|
359
|
-
body: String,
|
|
360
|
-
soundUri: String?,
|
|
361
|
-
vibrate: Boolean,
|
|
362
|
-
snoozeMinutes: Int,
|
|
363
|
-
autoStopSeconds: Int
|
|
364
|
-
) {
|
|
365
|
-
val alarmManager = reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
366
|
-
|
|
367
|
-
val intent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
368
|
-
action = "com.rnalarmmodule.ALARM_TRIGGER"
|
|
369
|
-
putExtra("alarmId", id)
|
|
370
|
-
putExtra("title", title)
|
|
371
|
-
putExtra("body", body)
|
|
372
|
-
putExtra("soundUri", soundUri ?: "")
|
|
373
|
-
putExtra("vibrate", vibrate)
|
|
374
|
-
putExtra("snoozeMinutes", snoozeMinutes)
|
|
375
|
-
putExtra("autoStopSeconds", autoStopSeconds)
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
val pendingIntent = PendingIntent.getBroadcast(
|
|
379
|
-
reactApplicationContext,
|
|
380
|
-
id.hashCode(),
|
|
381
|
-
intent,
|
|
382
|
-
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
383
|
-
)
|
|
384
209
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
AlarmManager.AlarmClockInfo(triggerTimeMillis, pendingIntent),
|
|
390
|
-
pendingIntent
|
|
391
|
-
)
|
|
392
|
-
} else {
|
|
393
|
-
// Fallback to inexact alarm if exact permission not granted
|
|
394
|
-
alarmManager.setAndAllowWhileIdle(
|
|
395
|
-
AlarmManager.RTC_WAKEUP,
|
|
396
|
-
triggerTimeMillis,
|
|
397
|
-
pendingIntent
|
|
398
|
-
)
|
|
399
|
-
Log.w(TAG, "Exact alarm permission not granted, using inexact alarm")
|
|
400
|
-
}
|
|
401
|
-
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
402
|
-
alarmManager.setAlarmClock(
|
|
403
|
-
AlarmManager.AlarmClockInfo(triggerTimeMillis, pendingIntent),
|
|
404
|
-
pendingIntent
|
|
405
|
-
)
|
|
210
|
+
val alarmManager = reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
211
|
+
val triggerAt = System.currentTimeMillis() + snoozeMinutes * 60_000L
|
|
212
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
213
|
+
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
|
|
406
214
|
} else {
|
|
407
|
-
alarmManager.setExact(
|
|
408
|
-
AlarmManager.RTC_WAKEUP,
|
|
409
|
-
triggerTimeMillis,
|
|
410
|
-
pendingIntent
|
|
411
|
-
)
|
|
215
|
+
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
|
|
412
216
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
private fun cancelScheduledAlarm(id: String) {
|
|
420
|
-
val alarmManager = reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
421
|
-
|
|
422
|
-
val intent = Intent(reactApplicationContext, AlarmReceiver::class.java).apply {
|
|
423
|
-
action = "com.rnalarmmodule.ALARM_TRIGGER"
|
|
217
|
+
Log.d(TAG, "Snoozed alarm for $snoozeMinutes minutes")
|
|
218
|
+
promise.resolve(null)
|
|
219
|
+
} catch (e: Exception) {
|
|
220
|
+
Log.e(TAG, "Failed to snooze alarm: ${e.message}")
|
|
221
|
+
promise.reject("SNOOZE_ERROR", e)
|
|
424
222
|
}
|
|
425
|
-
|
|
426
|
-
val pendingIntent = PendingIntent.getBroadcast(
|
|
427
|
-
reactApplicationContext,
|
|
428
|
-
id.hashCode(),
|
|
429
|
-
intent,
|
|
430
|
-
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
alarmManager.cancel(pendingIntent)
|
|
434
|
-
pendingIntent.cancel()
|
|
435
223
|
}
|
|
436
224
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
225
|
+
@ReactMethod
|
|
226
|
+
fun addListener(eventName: String) {
|
|
227
|
+
// Required for NativeEventEmitter
|
|
440
228
|
}
|
|
441
229
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
// Remove existing alarm with same ID
|
|
447
|
-
val filteredAlarms = JSONArray()
|
|
448
|
-
for (i in 0 until alarms.length()) {
|
|
449
|
-
val existingAlarm = alarms.getJSONObject(i)
|
|
450
|
-
if (existingAlarm.getString("id") != id) {
|
|
451
|
-
filteredAlarms.put(existingAlarm)
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
filteredAlarms.put(alarm)
|
|
456
|
-
prefs.edit().putString(ALARMS_KEY, filteredAlarms.toString()).apply()
|
|
230
|
+
@ReactMethod
|
|
231
|
+
fun removeListeners(count: Int) {
|
|
232
|
+
// Required for NativeEventEmitter
|
|
457
233
|
}
|
|
458
234
|
|
|
459
|
-
private fun
|
|
460
|
-
|
|
235
|
+
private fun saveAlarm(id: String, datetimeISO: String, title: String, body: String, snoozeEnabled: Boolean = true, snoozeInterval: Int = 5) {
|
|
236
|
+
val obj = JSONObject()
|
|
237
|
+
.put("id", id)
|
|
238
|
+
.put("datetimeISO", datetimeISO)
|
|
239
|
+
.put("title", title)
|
|
240
|
+
.put("body", body)
|
|
241
|
+
.put("snoozeEnabled", snoozeEnabled)
|
|
242
|
+
.put("snoozeInterval", snoozeInterval)
|
|
243
|
+
val prefs = reactApplicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
|
244
|
+
prefs.edit().putString(id, obj.toString()).apply()
|
|
461
245
|
}
|
|
462
246
|
|
|
463
247
|
private fun removeAlarm(id: String) {
|
|
464
|
-
val
|
|
465
|
-
|
|
466
|
-
for (i in 0 until alarms.length()) {
|
|
467
|
-
val existingAlarm = alarms.getJSONObject(i)
|
|
468
|
-
if (existingAlarm.getString("id") != id) {
|
|
469
|
-
filteredAlarms.put(existingAlarm)
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
prefs.edit().putString(ALARMS_KEY, filteredAlarms.toString()).apply()
|
|
248
|
+
val prefs = reactApplicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
|
249
|
+
prefs.edit().remove(id).apply()
|
|
473
250
|
}
|
|
474
251
|
|
|
475
|
-
private fun
|
|
476
|
-
val
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
252
|
+
private fun getAlarm(id: String): JSONObject? {
|
|
253
|
+
val prefs = reactApplicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
|
|
254
|
+
val jsonStr = prefs.getString(id, null) ?: return null
|
|
255
|
+
return try {
|
|
256
|
+
JSONObject(jsonStr)
|
|
257
|
+
} catch (_: Exception) {
|
|
258
|
+
null
|
|
482
259
|
}
|
|
483
|
-
return null
|
|
484
260
|
}
|
|
485
261
|
}
|
|
@@ -6,7 +6,6 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
6
6
|
import com.facebook.react.uimanager.ViewManager
|
|
7
7
|
|
|
8
8
|
class AlarmPackage : ReactPackage {
|
|
9
|
-
|
|
10
9
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
10
|
return listOf(AlarmModule(reactContext))
|
|
12
11
|
}
|