From ffbac0c7e3ede49d1354d7d1f36af22120fa4ece Mon Sep 17 00:00:00 2001 From: wellorbetter <1419919418@qq.com> Date: Thu, 26 Mar 2026 01:33:02 +0800 Subject: [PATCH 1/2] fix #202: fallback to default ringtone when alarm audio is missing --- .../org/fossify/clock/extensions/Context.kt | 23 +++++++++++++++++++ .../fossify/clock/services/AlarmService.kt | 17 ++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt b/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt index de9312736..4c73c74f1 100644 --- a/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt +++ b/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt @@ -12,6 +12,7 @@ import android.content.Intent import android.media.AudioAttributes import android.media.AudioManager.STREAM_ALARM import android.media.RingtoneManager +import android.net.Uri import android.os.Handler import android.os.Looper import android.text.SpannableString @@ -51,6 +52,7 @@ import org.fossify.clock.helpers.getDefaultTimeZoneTitle import org.fossify.clock.helpers.getTimeOfNextAlarm import org.fossify.clock.interfaces.TimerDao import org.fossify.clock.models.Alarm +import org.fossify.clock.models.AlarmEvent import org.fossify.clock.models.MyTimeZone import org.fossify.clock.models.Timer import org.fossify.clock.models.TimerState @@ -87,6 +89,7 @@ import java.util.Locale import kotlin.math.ceil import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.minutes +import org.greenrobot.eventbus.EventBus val Context.config: Config get() = Config.newInstance(applicationContext) @@ -557,6 +560,26 @@ fun Context.checkAlarmsWithDeletedSoundUri(uri: String) { it.soundUri = defaultAlarmSound.uri dbHelper.updateAlarm(it) } + EventBus.getDefault().post(AlarmEvent.Refresh) +} + +fun Context.isUriAccessible(uri: Uri): Boolean { + return try { + this.contentResolver.openAssetFileDescriptor(uri, "r")?.close() + true + } catch (e: Exception) { + false + } +} + +fun Context.isUriAccessible(uriString: String): Boolean { + if (uriString.isBlank()) return false + return try { + val uri = uriString.toUri() + isUriAccessible(uri) + } catch (e: Exception) { + false + } } fun Context.rotateWeekdays(days: List) = days.rotateLeft(config.firstDayOfWeek - 1) diff --git a/app/src/main/kotlin/org/fossify/clock/services/AlarmService.kt b/app/src/main/kotlin/org/fossify/clock/services/AlarmService.kt index 3d7b627b5..a85182f53 100644 --- a/app/src/main/kotlin/org/fossify/clock/services/AlarmService.kt +++ b/app/src/main/kotlin/org/fossify/clock/services/AlarmService.kt @@ -6,6 +6,7 @@ import android.media.AudioAttributes import android.media.AudioManager import android.media.AudioManager.STREAM_ALARM import android.media.MediaPlayer +import android.media.RingtoneManager import android.os.Handler import android.os.Looper import android.os.VibrationEffect @@ -13,13 +14,17 @@ import android.os.Vibrator import androidx.core.net.toUri import org.fossify.clock.activities.AlarmActivity import org.fossify.clock.extensions.alarmController +import org.fossify.clock.extensions.checkAlarmsWithDeletedSoundUri import org.fossify.clock.extensions.config import org.fossify.clock.extensions.dbHelper +import org.fossify.clock.extensions.isUriAccessible import org.fossify.clock.helpers.ALARM_ID import org.fossify.clock.helpers.ALARM_NOTIFICATION_ID import org.fossify.clock.helpers.AlarmNotificationHelper import org.fossify.clock.models.Alarm +import org.fossify.commons.extensions.getDefaultAlarmSound import org.fossify.commons.helpers.SILENT +import org.fossify.commons.helpers.ensureBackgroundThread import kotlin.time.Duration.Companion.seconds /** @@ -109,7 +114,15 @@ class AlarmService : Service() { } private fun startAlarmEffects(alarm: Alarm) { - if (alarm.soundUri != SILENT) { + var soundUri = alarm.soundUri + if (!isUriAccessible(soundUri)) { + ensureBackgroundThread { + checkAlarmsWithDeletedSoundUri(soundUri) + } + soundUri = applicationContext.getDefaultAlarmSound(RingtoneManager.TYPE_ALARM).uri + } + + if (soundUri != SILENT) { try { val audioAttributes = AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_ALARM) @@ -118,7 +131,7 @@ class AlarmService : Service() { mediaPlayer = MediaPlayer().apply { setAudioAttributes(audioAttributes) - setDataSource(this@AlarmService, alarm.soundUri.toUri()) + setDataSource(this@AlarmService, soundUri.toUri()) isLooping = true prepare() start() From 4a285a6034cbcac8360149f98e54fc030517b3e7 Mon Sep 17 00:00:00 2001 From: wellorbetter <1419919418@qq.com> Date: Thu, 26 Mar 2026 01:55:41 +0800 Subject: [PATCH 2/2] fix #202: fallback to default ringtone when alarm audio is missing --- app/src/main/kotlin/org/fossify/clock/extensions/Context.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt b/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt index 4c73c74f1..6f77af684 100644 --- a/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt +++ b/app/src/main/kotlin/org/fossify/clock/extensions/Context.kt @@ -567,7 +567,7 @@ fun Context.isUriAccessible(uri: Uri): Boolean { return try { this.contentResolver.openAssetFileDescriptor(uri, "r")?.close() true - } catch (e: Exception) { + } catch (_: Exception) { false } } @@ -577,7 +577,7 @@ fun Context.isUriAccessible(uriString: String): Boolean { return try { val uri = uriString.toUri() isUriAccessible(uri) - } catch (e: Exception) { + } catch (_: Exception) { false } }