Skip to content

Commit c37b000

Browse files
committed
wip
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent f0cdf41 commit c37b000

4 files changed

Lines changed: 67 additions & 1 deletion

File tree

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ dependencies {
476476

477477
// region iCal4j
478478
implementation(libs.ical4j) {
479-
listOf("org.apache.commons", "commons-logging").forEach { groupName -> exclude(group = groupName) }
479+
exclude(group = "commons-logging")
480480
}
481481
// endregion
482482

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
package com.nextcloud.utils.ical
8+
9+
import net.fortuna.ical4j.model.TimeZone
10+
import net.fortuna.ical4j.model.TimeZoneRegistry
11+
import net.fortuna.ical4j.model.TimeZoneRegistryImpl
12+
import java.time.ZoneId
13+
import java.time.zone.ZoneRules
14+
import java.util.concurrent.ConcurrentHashMap
15+
16+
/**
17+
* ical4j 4's default [TimeZoneRegistryImpl.register] publishes every timezone through
18+
* [net.fortuna.ical4j.model.ZoneRulesProviderImpl], which extends the platform
19+
* [java.time.zone.ZoneRulesProvider]. Both its constructor and
20+
* [java.time.zone.ZoneRulesProvider.registerProvider] are blocked hidden APIs on Android and
21+
* crash with a NoSuchMethodError.
22+
*
23+
* This registry keeps timezones defined inside parsed calendars in a local map and delegates
24+
* standard timezone lookups to a plain [TimeZoneRegistryImpl], whose read path never touches the
25+
* blocked provider.
26+
*/
27+
class AndroidCompatTimeZoneRegistry : TimeZoneRegistry {
28+
29+
private val delegate = TimeZoneRegistryImpl()
30+
private val registered = ConcurrentHashMap<String, TimeZone>()
31+
32+
override fun register(timezone: TimeZone) {
33+
registered[timezone.id] = timezone
34+
}
35+
36+
override fun register(timezone: TimeZone, update: Boolean) {
37+
register(timezone)
38+
}
39+
40+
override fun clear() {
41+
registered.clear()
42+
}
43+
44+
override fun getTimeZone(id: String): TimeZone? = registered[id] ?: delegate.getTimeZone(id)
45+
46+
override fun getZoneRules(): MutableMap<String, ZoneRules> = delegate.zoneRules
47+
48+
override fun getZoneId(tzId: String): ZoneId = delegate.getZoneId(tzId)
49+
50+
override fun getTzId(zoneId: String): String = delegate.getTzId(zoneId)
51+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
package com.nextcloud.utils.ical
8+
9+
import net.fortuna.ical4j.model.TimeZoneRegistry
10+
import net.fortuna.ical4j.model.TimeZoneRegistryFactory
11+
12+
class AndroidCompatTimeZoneRegistryFactory : TimeZoneRegistryFactory() {
13+
override fun createRegistry(): TimeZoneRegistry = AndroidCompatTimeZoneRegistry()
14+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# suppress inspection "UnusedProperty"
22
net.fortuna.ical4j.timezone.cache.impl=net.fortuna.ical4j.util.MapTimeZoneCache
3+
net.fortuna.ical4j.timezone.registry=com.nextcloud.utils.ical.AndroidCompatTimeZoneRegistryFactory

0 commit comments

Comments
 (0)