Loading src/androidTest/java/at/bitfire/ical4android/impl/TestCalendar.kt +1 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,7 @@ class TestCalendar( val values = ContentValues(3) values.put(CalendarContract.Calendars.NAME, "TestCalendar") values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "ical4android Test Calendar") values.put(CalendarContract.Calendars.ALLOWED_REMINDERS, CalendarContract.Reminders.METHOD_DEFAULT) values.put(CalendarContract.Calendars.ALLOWED_REMINDERS, CalendarContract.Reminders.METHOD_DEFAULT) val uri = AndroidCalendar.create(account, provider, values) TestCalendar(account, provider, ContentUris.parseId(uri)) Loading src/main/java/at/bitfire/ical4android/AndroidCalendar.kt +13 −6 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ import android.content.ContentProviderClient import android.content.ContentUris import android.content.ContentValues import android.net.Uri import android.provider.CalendarContract import android.provider.CalendarContract.* import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues import java.io.FileNotFoundException Loading @@ -30,18 +29,28 @@ abstract class AndroidCalendar<out T: AndroidEvent>( val provider: ContentProviderClient, val eventFactory: AndroidEventFactory<T>, /** the calendar ID ([CalendarContract.Calendars._ID]) **/ /** the calendar ID ([Calendars._ID]) **/ val id: Long ) { companion object { /** * Recommended initial values when creating Android [Calendars]. */ val calendarBaseValues = ContentValues(3) init { calendarBaseValues.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}") calendarBaseValues.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}") calendarBaseValues.put(Calendars.ALLOWED_REMINDERS, "${Reminders.METHOD_DEFAULT},${Reminders.METHOD_ALERT},${Reminders.METHOD_EMAIL}") } /** * Creates a local (Android calendar provider) calendar. * * @param account account which the calendar should be assigned to * @param provider client for Android calendar provider * @param info initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.) * @param info initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.) – *may be modified by this method* * * @return [Uri] of the created calendar * Loading @@ -51,9 +60,7 @@ abstract class AndroidCalendar<out T: AndroidEvent>( info.put(Calendars.ACCOUNT_NAME, account.name) info.put(Calendars.ACCOUNT_TYPE, account.type) // these values are generated by ical4android info.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}") info.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}") info.putAll(calendarBaseValues) Constants.log.info("Creating local calendar: $info") return provider.insert(syncAdapterURI(Calendars.CONTENT_URI, account), info) ?: Loading src/main/java/at/bitfire/ical4android/AndroidEvent.kt +27 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ import android.net.Uri import android.os.RemoteException import android.provider.CalendarContract.* import android.util.Base64 import android.util.Patterns import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues import net.fortuna.ical4j.model.* import net.fortuna.ical4j.model.Date Loading Loading @@ -310,15 +311,30 @@ abstract class AndroidEvent( val alarm = VAlarm(Dur(0, 0, -row.getAsInteger(Reminders.MINUTES), 0)) val props = alarm.properties props += when (row.getAsInteger(Reminders.METHOD)) { Reminders.METHOD_EMAIL, Reminders.METHOD_SMS -> Action.EMAIL else -> // show alarm by default Action.DISPLAY when (row.getAsInteger(Reminders.METHOD)) { Reminders.METHOD_EMAIL -> { val accountName = calendar.account.name if (Patterns.EMAIL_ADDRESS.matcher(accountName).matches()) { props += Action.EMAIL // ACTION:EMAIL requires SUMMARY, DESCRIPTION, ATTENDEE props += Summary(event.summary) props += Description(event.description ?: event.summary) // Android doesn't allow to save email reminder recipients, so we always use the // account name (should be account owner's email address) props += Attendee(URI("mailto", calendar.account.name, null)) } else { Constants.log.warning("Account name is not an email address; changing EMAIL reminder to DISPLAY") props += Action.DISPLAY props += Description(event.summary) } } // default: set ACTION:DISPLAY (requires DESCRIPTION) else -> { props += Action.DISPLAY props += Description(event.summary) } } event.alarms += alarm } Loading Loading @@ -622,7 +638,10 @@ abstract class AndroidEvent( val method = when (alarm.action?.value?.toUpperCase(Locale.US)) { Action.DISPLAY.value, Action.AUDIO.value -> Reminders.METHOD_ALERT // Note: The calendar provider doesn't support saving specific attendees for email reminders. Action.EMAIL.value -> Reminders.METHOD_EMAIL else -> Reminders.METHOD_DEFAULT } Loading Loading
src/androidTest/java/at/bitfire/ical4android/impl/TestCalendar.kt +1 −2 Original line number Diff line number Diff line Loading @@ -29,8 +29,7 @@ class TestCalendar( val values = ContentValues(3) values.put(CalendarContract.Calendars.NAME, "TestCalendar") values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "ical4android Test Calendar") values.put(CalendarContract.Calendars.ALLOWED_REMINDERS, CalendarContract.Reminders.METHOD_DEFAULT) values.put(CalendarContract.Calendars.ALLOWED_REMINDERS, CalendarContract.Reminders.METHOD_DEFAULT) val uri = AndroidCalendar.create(account, provider, values) TestCalendar(account, provider, ContentUris.parseId(uri)) Loading
src/main/java/at/bitfire/ical4android/AndroidCalendar.kt +13 −6 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ import android.content.ContentProviderClient import android.content.ContentUris import android.content.ContentValues import android.net.Uri import android.provider.CalendarContract import android.provider.CalendarContract.* import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues import java.io.FileNotFoundException Loading @@ -30,18 +29,28 @@ abstract class AndroidCalendar<out T: AndroidEvent>( val provider: ContentProviderClient, val eventFactory: AndroidEventFactory<T>, /** the calendar ID ([CalendarContract.Calendars._ID]) **/ /** the calendar ID ([Calendars._ID]) **/ val id: Long ) { companion object { /** * Recommended initial values when creating Android [Calendars]. */ val calendarBaseValues = ContentValues(3) init { calendarBaseValues.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}") calendarBaseValues.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}") calendarBaseValues.put(Calendars.ALLOWED_REMINDERS, "${Reminders.METHOD_DEFAULT},${Reminders.METHOD_ALERT},${Reminders.METHOD_EMAIL}") } /** * Creates a local (Android calendar provider) calendar. * * @param account account which the calendar should be assigned to * @param provider client for Android calendar provider * @param info initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.) * @param info initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.) – *may be modified by this method* * * @return [Uri] of the created calendar * Loading @@ -51,9 +60,7 @@ abstract class AndroidCalendar<out T: AndroidEvent>( info.put(Calendars.ACCOUNT_NAME, account.name) info.put(Calendars.ACCOUNT_TYPE, account.type) // these values are generated by ical4android info.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}") info.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}") info.putAll(calendarBaseValues) Constants.log.info("Creating local calendar: $info") return provider.insert(syncAdapterURI(Calendars.CONTENT_URI, account), info) ?: Loading
src/main/java/at/bitfire/ical4android/AndroidEvent.kt +27 −8 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ import android.net.Uri import android.os.RemoteException import android.provider.CalendarContract.* import android.util.Base64 import android.util.Patterns import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues import net.fortuna.ical4j.model.* import net.fortuna.ical4j.model.Date Loading Loading @@ -310,15 +311,30 @@ abstract class AndroidEvent( val alarm = VAlarm(Dur(0, 0, -row.getAsInteger(Reminders.MINUTES), 0)) val props = alarm.properties props += when (row.getAsInteger(Reminders.METHOD)) { Reminders.METHOD_EMAIL, Reminders.METHOD_SMS -> Action.EMAIL else -> // show alarm by default Action.DISPLAY when (row.getAsInteger(Reminders.METHOD)) { Reminders.METHOD_EMAIL -> { val accountName = calendar.account.name if (Patterns.EMAIL_ADDRESS.matcher(accountName).matches()) { props += Action.EMAIL // ACTION:EMAIL requires SUMMARY, DESCRIPTION, ATTENDEE props += Summary(event.summary) props += Description(event.description ?: event.summary) // Android doesn't allow to save email reminder recipients, so we always use the // account name (should be account owner's email address) props += Attendee(URI("mailto", calendar.account.name, null)) } else { Constants.log.warning("Account name is not an email address; changing EMAIL reminder to DISPLAY") props += Action.DISPLAY props += Description(event.summary) } } // default: set ACTION:DISPLAY (requires DESCRIPTION) else -> { props += Action.DISPLAY props += Description(event.summary) } } event.alarms += alarm } Loading Loading @@ -622,7 +638,10 @@ abstract class AndroidEvent( val method = when (alarm.action?.value?.toUpperCase(Locale.US)) { Action.DISPLAY.value, Action.AUDIO.value -> Reminders.METHOD_ALERT // Note: The calendar provider doesn't support saving specific attendees for email reminders. Action.EMAIL.value -> Reminders.METHOD_EMAIL else -> Reminders.METHOD_DEFAULT } Loading