ICSx⁵ is an Android app to subscribe to remote or local iCalendar files (like time tables of your school/university or event files of your sports team).

Related tags

App icalendar webcal
Overview

Tests License F-Droid

ICSx⁵

ICSx⁵ is an Android app to subscribe to remote Webcal feeds / iCalendar files (like time tables of your school/university or event files of your sports team).

Please see the ICSx⁵ Web site for comprehensive information about ICSx⁵.

News and updates: @icsx5app

Help, discussion, ideas, bug reports: ICSx⁵ forum

We're happy about contributions! Just send a pull request for small changes or in case of bigger changes, please let us know in the forum before.

License

ICSx⁵ is licensed under the GPLv3 License.

Copyright © Ricki Hirner (bitfire web engineering GmbH) and contributors.

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU GPL v3.

Comments
  • Customizable alarms per subscription

    Customizable alarms per subscription

    • Support customizable alarms per subscription (for instance: add an alarm 10 min before the event for every event in the subscription)
      • [x] Create UI for setting per subscription: "Add custom alarm" (Edit calendar activity)
      • [x] Save setting per subscription: "Add custom alarm"
      • [x] Actually make this setting work
    • Possibility to disable alarms which come with the .ics
      • [x] Create UI for setting per subscription: "Ignore alarms from file" (Edit calendar activity)
      • [x] Save setting per subscription: "Ignore alarms from file"
      • [x] Actually make this setting work
    enhancement 
    opened by rfc2822 13
  • Do Not Disturb cannot see subscribed .ics calendars

    Do Not Disturb cannot see subscribed .ics calendars

    Discussed in https://github.com/bitfireAT/icsx5/discussions/40

    Originally posted by emacsomancer March 17, 2022 On an Android 10 device I was able to subscribe to an .ics calendar via ICSx5 and have Do Not Disturb turn on during calendar events from that calendar, but on my Android 12/GrapheneOS device Do Not Disturb doesn't seem to be able to 'see' that calendar (though it can see locally created calendars).

    enhancement 
    opened by ArnyminerZ 11
  • Android 11: move from file URIs to SAF

    Android 11: move from file URIs to SAF

    Since Android 10, file URIs shouldn't/can't access files outside the own application anymore. Since Android 11, file URIs for shared files are possible again, but the better method is SAF and content URIs.

    So ICSx⁵ should support SAF instead of file:// URIs.

    enhancement 
    opened by rfc2822 11
  • Android 13 compatibility

    Android 13 compatibility

    Raise target level to Android 13

    • [x] handle notification permission (docs)
    • [x] predictive back gesture (docs)
      • [x] Update androidx.appcompat:appcompat to 1.6.0-rc01 (Release notes)
    • [x] per-app language preferences (docs)
    • [x] themed icon (monochrome) (docs)
    • [ ] check whether anything else has changed
    • [x] update libraries and dependencies
      • [x] Update AGP to 7.3.1
        • [x] Move package from Android manifest to build files (see)
        • [x] Update desugaring lib to 1.2.0 (docs)
      • [x] Update Kotlin to 1.7.20
      • [x] Update androidx.test.runner to 1.5.0 (no breaking changes - Release notes)
      • [x] Update androidx.test:rules to 1.5.0 (no breaking changes - Release notes)
      • [x] Update com.google.android.material:material to 1.7.0 (Release notes)
        • [x] Requirement of AGP >=7.2.0 (we are using 7.2.2 -> 7.3.1)
        • [x] Requirement of Gradle >=7.3.3 (we are using 7.4.2)
        • [x] Requirement of Java 8
      • [x] Update androidx.core:core-ktx to 1.9.0 (Release notes - Improves compatibility with Android 13)
      • [x] Update androidx.fragment:fragment-ktx to 1.5.4 (Release notes - Just bugfixes)
    • [x] raise target level (targetSdkVersion) to 33
    • [x] raise compile level (compileSdkVersion) to 33 and build tools (buildToolsVersion) to 33.0.0
    opened by rfc2822 8
  • Get calendar color when at subscription

    Get calendar color when at subscription

    Calendars (Webcal feeds) can contain a color that shall be used for the whole calendar.

    Possible representation:

    • COLOR (RFC 7986)
    • X-APPLE-CALENDAR-COLOR, see https://github.com/bitfireAT/icsx5/discussions/29#discussioncomment-2328294

    This color could be used as a suggestion when adding a calendar.

    • [ ] ResourceInfo: add calendarColor like calendarName
    • [ ] AddCalendarValidationFragment.ValidationModel: get calendar color like calendar name
    • [ ] AddCalendarValidationFragment: set initial color from calendar color (fall back to lightblue)
    enhancement 
    opened by rfc2822 6
  • Workaround needed for AppleWebObjects

    Workaround needed for AppleWebObjects

    This has been reported by a user when adding certain calendars to ICSx5.

    Adding: webcal://hhv-handball.liga.nu/cgi-bin/WebObjects/nuLigaHBDE.woa/wa/getTeamMeetingsWebcal?teamid=1457876 will throw an error:

    HTTP 401 Apple WebObjects java.io.IOException: HTTP 401 Apple WebObjects at at.bitfire.icsdroid.CalendarFetcher.fetchNetwork$icsx5_62_2_0_2_gplayRelease(CalendarFetcher.kt:179) at at.bitfire.icsdroid.CalendarFetcher.onRedirect(CalendarFetcher.kt:83) at at.bitfire.icsdroid.CalendarFetcher.fetchNetwork$icsx5_62_2_0_2_gplayRelease(CalendarFetcher.kt:171) at at.bitfire.icsdroid.CalendarFetcher.run(CalendarFetcher.kt:46) at java.lang.Thread.run(Thread.java:1012)

    While calendars from the same source with different events work:

    webcal://hhv-handball.liga.nu/cgi-bin/WebObjects/nuLigaHBDE.woa/wa/getTeamMeetingsWebcal?teamid=1458151 webcal://hhv-handball.liga.nu/cgi-bin/WebObjects/nuLigaHBDE.woa/wa/getTeamMeetingsWebcal?teamid=1457879

    Not super urgent but we should take look at this if we can workaround this.

    invalid 
    opened by devvv4ever 3
  • (Dark mode?) after installing doesn't show calendar list

    (Dark mode?) after installing doesn't show calendar list

    1. (Switch device to dark mode)
    2. Install latest ICSx5 from Google Play, launch it, allow calendar access
    3. Add a subscription
    4. The subscription is there, but not shown – only a black screen, see screenshot below.

    When the theme is changed to light theme or when ICSx⁵ is killed in the task manager and started again, everything works.

    Screenshot_1662483490

    bug 
    opened by rfc2822 3
  • should give proper error message when a synced file is deleted

    should give proper error message when a synced file is deleted

    At the moment the user only sees a message like the following

    java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/msf%3A68 from pid=20876, uid=10151 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
    

    To reproduce either

    • Pick a file, then before adding it,
    • delete the file using filemanager,
    • return to the app and "add" the file.

    or

    • Add the file normally, then
    • delete it via filemanager
    • try to sync manually
    enhancement 
    opened by sunkup 3
  • Allow use of user-installed CAs

    Allow use of user-installed CAs

    Fixes #43

    As per https://developer.android.com/training/articles/security-config Previous behaviour: only validated certificates in the system certificate authority store New behaviour: validates against both system CAs and user-installed CAs

    opened by harryyoud 2
  • WIP: Customizable alarms per subscription

    WIP: Customizable alarms per subscription

    Closes #1

    Bugs:

    • [x] The alerts removal for when the "ignore embed alarms" option is checked only works the first time you add the calendar. This is caused by ProcessEventsTask: https://github.com/bitfireAT/icsx5/blob/a52b5a3ef1af1014b3ad8d75b1683cb69bb5d459/app/src/main/java/at/bitfire/icsdroid/ProcessEventsTask.kt#L87 Since the calendar is technically not modified, only locally, onNotModified is called. There should be logic to handle changes to the ignore embed alarms switch, which add back again all the alarms.

    TODO:

    • [x] Custom reminders only get stored for the synchronization, they don't get added to the events.
    enhancement 
    opened by ArnyminerZ 1
  • Error while adding meetup calendar to ICSx5 or DavX5

    Error while adding meetup calendar to ICSx5 or DavX5

    Steps to reproduce:

    1. Go to meetup.com > My Events
    2. Click on Sync Calendar > Outlook . Copy the link
    3. In ICS X5 , click on + button and paste link in ICSX5 in URL box
    4. Click on Next arrow on top right

    Observed behavior

    1. Error message "Couldn't parse iCalendar
    Couldn't parse iCalendar
    
    at.bitfire.ical4android.InvalidCalendarException: Couldn't parse iCalendar
    	at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:84)
    	at at.bitfire.ical4android.Event$Companion.eventsFromReader(Event.kt:84)
    	at at.bitfire.icsdroid.ui.AddCalendarValidationFragment$ValidationModel$initialize$downloader$1.onSuccess(AddCalendarValidationFragment.kt:114)
    	at at.bitfire.icsdroid.CalendarFetcher.fetchNetwork(CalendarFetcher.kt:133)
    	at at.bitfire.icsdroid.CalendarFetcher.onRedirect(CalendarFetcher.kt:79)
    	at at.bitfire.icsdroid.CalendarFetcher.fetchNetwork(CalendarFetcher.kt:147)
    	at at.bitfire.icsdroid.CalendarFetcher.run(CalendarFetcher.kt:44)
    	at java.lang.Thread.run(Thread.java:764)
    Caused by: net.fortuna.ical4j.data.ParserException: Error at line 149:Attempt to invoke virtual method 'void java.util.Calendar.setTimeZone(java.util.TimeZone)' on a null object reference
    	at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:162)
    	at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:183)
    	at net.fortuna.ical4j.data.CalendarBuilder.build(CalendarBuilder.java:171)
    	at at.bitfire.ical4android.ICalendar$Companion.fromReader(ICalendar.kt:82)
    	... 7 more
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Calendar.setTimeZone(java.util.TimeZone)' on a null object reference
    	at java.text.DateFormat.setTimeZone(DateFormat.java:690)
    	at net.fortuna.ical4j.model.Iso8601.<init>(Iso8601.java:78)
    	at net.fortuna.ical4j.model.Date.<init>(Date.java:150)
    	at net.fortuna.ical4j.model.DateTime.<init>(DateTime.java:262)
    	at net.fortuna.ical4j.model.TimeZone.inDaylightTime(TimeZone.java:143)
    	at java.util.TimeZone.getOffsets(TimeZone.java:246)
    	at java.util.GregorianCalendar.adjustForZoneAndDaylightSavingsTime(GregorianCalendar.java:2916)
    	at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2807)
    	at java.util.Calendar.updateTime(Calendar.java:3397)
    	at java.util.Calendar.getTimeInMillis(Calendar.java:1761)
    	at java.util.Calendar.getTime(Calendar.java:1734)
    	at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1633)
    	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1528)
    	at java.text.DateFormat.parse(DateFormat.java:360)
    	at net.fortuna.ical4j.model.DateTime.setTime(DateTime.java:418)
    	at net.fortuna.ical4j.model.DateTime.<init>(DateTime.java:325)
    	at net.fortuna.ical4j.model.property.DateProperty.setValue(DateProperty.java:138)
    	at net.fortuna.ical4j.data.DefaultContentHandler.resolveTimezones(DefaultContentHandler.java:218)
    	at net.fortuna.ical4j.data.DefaultContentHandler.endCalendar(DefaultContentHandler.java:86)
    	at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendar(CalendarParserImpl.java:130)
    	at net.fortuna.ical4j.data.CalendarParserImpl.parseCalendarList(CalendarParserImpl.java:184)
    	at net.fortuna.ical4j.data.CalendarParserImpl.parse(CalendarParserImpl.java:153)
    	... 10 more`
    
    opened by vortexmak 1
  • Credentials should be stored in `EncryptedSharedPreferences`

    Credentials should be stored in `EncryptedSharedPreferences`

    Right now, credentials are being stored inside regular SharedPreferences in CalendarCredentials: https://github.com/bitfireAT/icsx5/blob/0b1443de38e0e32f147351ae36358c01af710236/app/src/main/java/at/bitfire/icsdroid/db/CalendarCredentials.kt#L17-L19

    EncryptedSharedPreferences shall be used.

    The change is quite simple, they provide a good example:

    MasterKey masterKey = new MasterKey.Builder(context)
         .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
         .build();
    
     SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
         context,
         "secret_shared_prefs",
         masterKey,
         EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
         EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
     );
    
     // use the shared preferences and editor as you normally would
     SharedPreferences.Editor editor = sharedPreferences.edit();
    
    refactoring 
    opened by ArnyminerZ 1
  • Move subscriptions to database

    Move subscriptions to database

    If we would move the subscriptions to an app-local database (instead of creating them directly in the Calendar Provider as calendars), we wouldn't have to rely on the Calendar Provider anymore. This would bring some beneftis:

    • For authentication we already use some kind of DB (encrypted shared preferences); a real DB would allow to store authentication and other settings together with the subscription without having to use a limited number of _SYNC columns
    • Settings wouldn't be exposed to other apps.
    • Sometimes accounts are removed by devices (for instance on system upgrades). Then all subscriptions are gone. If we store them ourselves, they would still be there and the calendars can be re-created on sync.
    • Same for backup (#4) – we could then just use autoFullBackup without any extra code.
    • We only need to ask for calendar permissions when there are active subscriptions :)

    Steps to implement:

    1. Manage subscriptions locally – Room DB (or maybe shared preferences or whatever seems feasible – but I think other things than Room will again add more "dirtyness").
    2. The sync worker would have to
    • create the account (if it's not already there),
    • create/update calendars from the local subscription DB,
    • sync the calendars.
    refactoring 
    opened by rfc2822 2
  • Couldn't connect to server

    Couldn't connect to server

    Updating the calendars doesn't work regularly. Error message: "Couldn't connec to server."

    Seems like the Internet connection is not ready yet when the work manager initiates the synchronization.

    Similar to #24

    bug 
    opened by rfc2822 18
  • ICSx⁵ crashes with a Security-Exception at at.bitfire.icsdroid.AppAccount.get

    ICSx⁵ crashes with a Security-Exception at at.bitfire.icsdroid.AppAccount.get

    It seems the system can't access the calendar list of an ICSx⁵ account (at.bitfire.icsdroid.AppAccount.get)? Maybe we should just try-catch this and handle this case properly?

    This happens on many different Samsung devices so far as well as on a Google Pixel 5 and so far only on Android 11 and 12.

    java.lang.RuntimeException: 
      at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:4022)
      at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4188)
      at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:103)
      at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
      at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
      at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2425)
      at android.os.Handler.dispatchMessage (Handler.java:106)
      at android.os.Looper.loopOnce (Looper.java:226)
      at android.os.Looper.loop (Looper.java:313)
      at android.app.ActivityThread.main (ActivityThread.java:8582)
      at java.lang.reflect.Method.invoke (Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:563)
      at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1133)
    Caused by: java.lang.SecurityException: 
      at android.os.Parcel.createExceptionOrNull (Parcel.java:2437)
      at android.os.Parcel.createException (Parcel.java:2421)
      at android.os.Parcel.readException (Parcel.java:2404)
      at android.os.Parcel.readException (Parcel.java:2346)
      at android.accounts.IAccountManager$Stub$Proxy.addAccountExplicitly (IAccountManager.java:1550)
      at android.accounts.AccountManager.addAccountExplicitly (AccountManager.java:1030)
      at at.bitfire.icsdroid.AppAccount.get (AppAccount.kt:50)
      at at.bitfire.icsdroid.ui.CalendarListActivity$CalendarModel.loadCalendars (CalendarListActivity.kt:332)
      at at.bitfire.icsdroid.ui.CalendarListActivity$CalendarModel.startWatchingCalendars (CalendarListActivity.kt:318)
      at at.bitfire.icsdroid.ui.CalendarListActivity$CalendarModel.reinit (CalendarListActivity.kt:301)
      at at.bitfire.icsdroid.ui.CalendarListActivity.onCreate (CalendarListActivity.kt:98)
      at android.app.Activity.performCreate (Activity.java:8282)
      at android.app.Activity.performCreate (Activity.java:8262)
      at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1329)
      at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3996)
      at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4188)
      at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:103)
      at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
      at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
      at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2425)
      at android.os.Handler.dispatchMessage (Handler.java:106)
      at android.os.Looper.loopOnce (Looper.java:226)
      at android.os.Looper.loop (Looper.java:313)
      at android.app.ActivityThread.main (ActivityThread.java:8582)
      at java.lang.reflect.Method.invoke (Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:563)
      at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1133)
    Caused by: android.os.RemoteException: 
      at com.android.server.accounts.AccountManagerService.addAccountExplicitlyWithVisibility (AccountManagerService.java:501)
      at com.android.server.accounts.AccountManagerService.addAccountExplicitly (AccountManagerService.java:1776)
      at android.accounts.IAccountManager$Stub.onTransact (IAccountManager.java:583)
      at com.android.server.accounts.AccountManagerService.onTransact (AccountManagerService.java:1119)
      at android.os.Binder.execTransactInternal (Binder.java:1215)
    
    bug 
    opened by devvv4ever 3
Owner
bitfire web engineering
bitfire web engineering
eduJam is an university app, which will help you with all of your university work*

eduJam - Your one-stop to any university work eduJam is an university app, which will help you with all of your university work. It has features which

Dhiraj Chauhan 16 Nov 24, 2022
Football live time league tables

footballLiveScoresApp Football live scores App Football Mania Live scores gives results in competitions, players and teams from english leagues like p

Ro'ziboyev Ismoil 3 Apr 30, 2022
Clean architecture dictionary app fetching remote data with local caching

ComposeDictionary Clean architecture dictionary app fetching remote data with local caching Installation Clone this repository and import into Android

Timothy Serem 2 Feb 19, 2022
Usages of Factory Method for Data Source Layer (Local/Remote - Repository) with DI & MVVM [Android].

Usages of Factory Method for Data Source Layer (Local/Remote - Repository) with DI & MVVM [Android] Stacks: MVVVM DI (Hilt) Factory Method (Design Pat

Romman Sabbir 4 Aug 9, 2022
A reliable android app that shows upcoming fixtures, updated league tables, and top goal scorers in a Premier League and French Ligue 1

RapidScore Screenshots Table of Contents Description Dependencies API Reference Lessons Learnt Contributing Roadmap Google Playstore License Author In

Breens Mbaka 12 Jul 7, 2022
Progressive Web App that allows you to create workout tables

WORKOUT Progressive Web App that allows you to create workout tables. ...work in

Piero 0 Jan 10, 2022
The platform for time-management by pomodoro technique between team.

❗️ Moved to tomadoro organization. ?? Pomodoro The platform for time-management by pomodoro technique between team with lot of customization. Pomodoro

Vadim Yaroschuk 8 Dec 8, 2022
PortalController - A rudimentary TeamViewer-like remote control app for Android, using ws.

PortalController A TeamViewer-like app for Android-to-Android remote control, using node.js and websockets (ws). Some insight The reason I call it rud

Mike Anderson 10 Dec 15, 2022
School project: Weather forecast application made in android studio using Kotlin, SQLite and OpenWeatherMaps free API.

A*star 4-cast School project made in android studio using Kotlin, SQLite and free API from OpenWeatherMap.org. A weather forecast app with C(U)RD oper

Felicia Olsson 2 Apr 3, 2022
Rolling Scopes School - Android 2021 - Stage 1 - Task 2 - Quiz

rsschool2021-Android-task-quiz Rolling Scopes School - Android 2021 - Stage 1 - Task 2 - Quiz ☝️ Во втором практическом задании создадим приложение-кв

null 0 Jan 13, 2022
A news app made using android studio in Java with features like favourite news, Location detector for local news, and especially made with HUAWEI APIs

HuaweiGlobalNewsApp A news app made using android studio in Java with features like favourite news, Location detector for local news, and especially m

Christian Imanuel Hadiwidjaja 1 Oct 30, 2021
Jiangxi Normal University Android App

Awesome-Campus Jiangxi Normal University Android App 简介 师大+是江西师大Android客户端,包含课表、课程表桌面小部件、校内新闻、阅读资讯、快递查询、考试安排、成绩查询、图书借阅等功能模块。 它采用卡片式设计,遵循Material Desig

Danielding 119 Nov 10, 2022
An Android app built with Kotlin, to help students at Kibabii University make monthly class welfare contributions

An Android app built with Kotlin, to help students at Kibabii University make monthly class welfare contributions. It is built with the MVVM pattern and the latest Jetpack components. Firebase as the backend

Joel Kanyi 21 Sep 24, 2022
Plannr is an organizational platform, in the form of an Android app, that helps university students coordinate their everyday routine, from schoolwork and expenses to their personal life.

Plannr Plannr is an organizational platform, in the form of an Android app, that helps university students coordinate their everyday routine, from sch

null 7 May 1, 2022
SkillHub - A location based native android app built for the University of Nigeria

SkillHub SkillHub is a location based native android app built for the Universit

Nnamani Chinonso   1 Jan 23, 2022
when you use restful api and network get disconnect you have to store your data local for make your app faster and work on ofline mode

AppArchitectureOflineMode when you use restful api and network get disconnect you have to store your data local for make your app faster and work on o

Kareem-Mansy 3 Jun 20, 2021
Android Study Jams - These are applications built for Android Study Jams 2022 at Chitkara University

Project Description These are applications built for Android Study Jams 2022 at

Armaan Jain 3 Sep 16, 2022
Hanyang-ktheme-android - Kakaotalk theme with Ha-nyang and other characters from Hanyang University

한양대 ERICA 카카오톡 테마 한양대 ERICA의 캐릭터(하냥이/하이비비)를 사용한 카카오톡 테마의 Android 버전입니다. 캐릭터의 저작권은 한양대 ERICA에 있습니다. 정보 원저작자 : 한양대 ERICA 대외협력팀 작업자 : 이정인 (컴퓨터전공 17) 카카오톡

Jeongin Lee 0 Jan 5, 2022