Skip to content

Calendar Provider

Calendar provider plugins need to extend the CalendarProvider class:

kt
class MyCalendarPlugin() : CalendarProvider(
    QueryPluginConfig()
)

In the super constructor call, pass a QueryPluginConfig object.

Plugin config

Search plugins have the following configuration properties:

  • storageStrategy: Describes how the launcher should store a search result in its internal database. This is relevant when a user pins a search result to favorites, or when they assign a tag or custom label. In these situations, the launcher needs to be able to restore the search result from its database. There are two different strategies:
    • StorageStrategy.StoreCopy (default): The launcher stores all relevant information about this search result in its own internal database. The result can be restored without querying the plugin again. The launcher will try refresh the search result at its own discretion (e.g. when a user long-presses a restored search result to view its details). This strategy is the default and should be used whenever the plugin can't restore a search result immediately. It is best suited for online search plugins.
    • StorageStrategy.StoreReference: The launcher only stores the ID of the search result, and the plugin that created it. To restore a result, the plugin is queried again. This allows the plugin to update key fields (i.e. the label) immediately. However, plugins that use this strategy must guarantee, that they can restore a search result at any time, in a timely manner. In particular, the plugin must be able to restore a search result without any network requests. This strategy is best suited for on-device search plugins.

Calendar lists

Calendar lists are collections of calendar entries (i.e. "Private", "Work", "Family"). Users can choose, which lists to include in search results and the calendar widget. To implement calendar lists, override

kt
suspend fun getCalendarLists(): List<CalendarList>

This method should return a list of CalendarLists. At least one list should be returned.

The CalendarList object

The CalendarEvent has the following properties:

  • id: A unique ID for this list.
  • name: A human-readable name for this list.
  • contentTypes: A list of CalendarListTypes (Calendar, Tasks) that this list includes.
  • accountName (optional): The name of the account this list belongs to. Lists that belong to the same account are grouped together in the launcher UI.
  • color (optional): The color of this list, in 0xAARRGGBB format.

Search calendar events

Calendar search is used by both search and calendar widget. To implement calendar search, override

kt
suspend fun search(query: CalendarQuery, params: SearchParams): List<CalendarEvent>
  • query includes the query parameters:

    • query: The search term. Can be null if the query was started by the calendar widget.
    • start: The timestamp (ms since epoch) of the start of the search window.
    • end: The timestamp (ms since epoch) of the end of the search window.
    • excludedCalendars: List of calendar list IDs that should be excluded from the search results.
  • params provides additional parameters for the search:

    • allowNetwork is a flag that indicates whether the user has enabled online search for this query. Plugins are generally advised to respect this request. This flag exists mainly for privacy reasons: the majority of searches target offline results (like apps, or contacts). Sending every single search request to external servers is overkill and can be a privacy issue. (Besides, it's not very nice to overload servers with unnecessary requests.) To reduce the amount of data that is sent to external servers, users can control, whether a search should include online results or not.
    • lang is the current language of the launcher. This can differ from the system language, as the user can set a different language per app. This value should be used for any localization in the search results.

search returns a list of CalendarEvents. The list can be empty if no results were found.

The CalendarEvent object

A CalendarEvent has the following properties:

  • id: A unique ID for this event.
  • title: The title of the event.
  • calendarName: The name of the calendar the event belongs to.
  • description (optional): A description of the event.
  • location (optional): The location of the event.
  • attendees: A list of human-readable names, representing the attendees.
  • color (optional): The color of the event, in 0xAARRGGBB format.
  • startTime: Start time of the event in milliseconds since epoch. For tasks, this can be null.
  • endTime: End time of the event in milliseconds since epoch. For tasks, this is the due date.
  • includeTime: If false, only the date will be shown for the event.
  • uri: A URI that opens the event. Can be a URI that your app can handle, or a weblink.
  • isCompleted (optional): If this is not null, the event is treated as a task, indicated by a checkmark in the UI.

Refresh an event

If you have set config.storageStrategy to StorageStrategy.StoreCopy, the launcher will periodically try to refresh the stored copy. This happens for example when a user long-presses an event to view its details. To update the event, you can override

kt
suspend fun refresh(item: CalendarEvent, params: RefreshParams): CalendarEvent?

The stored event will be replaced with the return value of this method. If the event is no longer available, it should return null. In this case, the launcher will remove it from its database. If the event is temporarily unavailable, an exception should be thrown.

  • item is the version that the launcher has currently stored

  • params provides additional parameters:

    • lang is the current language of the launcher. This can differ from the system language, as the user can set a different language per app. This value should be used to localize the result.
    • lastUpdated the timestamp (in milliseconds) when item was last updated. This should be used to determine if the item needs to be refreshed again. If you decide not to refresh the item, you should return the original item parameter.

The default implementation returns item without any changes.

Get an event

If you have set config.storageStrategy to StorageStrategy.StoreReference, you must override

kt
suspend fun get(id: String, params: GetParams): CalendarEvent?

This method is used to look up a event by its id. If the event is no longer available, it should return null. In this case, the launcher will remove it from its database.

  • id is the ID of the event that is being requested

  • params provides additional parameters:

    • lang is the current language of the launcher. This can differ from the system language, as the user can set a different language per app. This value should be used to localize the result.

Plugin state

Some plugins need to be configured before they can be used. For example, users might need to connect an account, or provide an API key.

If your plugin has such requirements, you can override

kt
suspend fun getPluginState(): PluginState

This method can either return PluginState.Ready, or PluginState.SetupRequired.

  • PluginState.Ready can have a status text to describe what the plugin does in its current configuration. For example "Search {username}'s files on {service}". This overrides the plugin's description.
  • PluginState.SetupRequired needs to have a setupActivity Intent that starts the setup. You can also provide a message to describe what kind of setup needs to be performed. For example "Sign in with {service} to search files on {service}"

IMPORTANT

This method is only meant to provide hints to the launcher's user interface. You should not rely on it as a safeguard for your other plugin methods. There is still a chance that your other plugin methods are called regardless of the return value of this method. Make sure to check your requirements in the other plugin methods as well.

Additional notes

Calendar widget

The calendar widget uses the same search method that the search uses. The only difference is that query.query is always null and that params.allowNetwork is always false.

Actions

To handle the calendar widget actions (addCreate new event, open_in_new Open calendar app), your app should be able to handle the following intents:

Tasks

Tasks are a special type of calendar event, because they can be completed or uncompleted. A CalendarEvent is treated as a task, when its isCompleted property is not null. For tasks, the endTime is the due date. The startTime is the time from which the task should be displayed, and it can be null to always display the task.

Examples