This section of the documentation covers information for developers.
To develop K-9 you need a working understanding of:
With just Java knowledge you may be able to make minor logic changes and small fixes. But the Android APIs are used extensively (as well as Android based libraries), particularly in the front-end.
XML provides the translation (however that’s pulled in from Transifex anyway) and some of UI layout.
Once you’ve gained a solid understanding of these we recommend you look at our existing issues and pick one tagged ‘good first issue’. If there’s not a tagged one not being worked on then feel free to pick an issue that interests you. If there’s no developer comments on the issue you select (and it’s not marked beginner) feel free to ask about the best approach before you start!
To build the project simply clone the repository and import the project into Android Studio. From there you can use the IDE tools to build the k9mail APK and install it.
The general structure of K-9 is as follows:
- k9mail - Main module - includes code for activities, notification, database interaction, settings and encryption
- k9mail-library - Back-end code for contacting mail providers and decoding emails from MIME
- Android-PullToRefresh library - Library for implementing ‘pull to refresh’ lists
- openpgp-api - Library for interacting with OpenPGP providers (e.g. OpenKeychain)
- HoloColorPicker - A colour picker for the Holo Android theme
There are many parts to K-9. This list gives a rough outline of some of them.
- Stores (
.mail.store.*) - Each receiving protocol (IMAP, POP3 and WebDAV) is implemented as a store (e.g. ImapStore). This store maintains connections (e.g. ImapConnection), and provide access to Folders (e.g. ImapFolder). which correspond to email folders that store messages (ImapMessage).
- Transports (
.mail.transport.*) - Each sending protocol (SMTP, WebDAV) is implemented as Transport that must establish a connection to send e-mail.
- Messages (
.mail.internet.*) - A message is comprised of Parts. The type of part actually used depends on whether the message is a RemoteMessage, waiting for download, mid-download (MemoryParts) or stored in the database (LocalPart).
- MessagingController (
.controller.MessagingController) - This key class is responsible for syncing and handling user actions. For example, it has methods to queue synchronization of messages.
- Activities and Fragments (
.fragments) - These back the various layout files to react to and display information to the user.
- Notifications (
.notification) - This comprises the Android notification handling
This section highlights some of the layout files in use.
account_setup_*- Views relating to account setup
accounts- The Accounts view
message_list- Renders the message list and view. Delegates to
messagedepending on settings and requirements.
message_list_fragment- Renders the message list (a
message- Renders a message, delegating to
message_compose- Renders the screen when composing a message. Delegates to
message_compose_recipientsand provides a list of
message_compose_attachments. Uses a combination of enhanced
MessageWebViewfor the message to be sent
message_container- Renders a message content, delegating to
message_list_item- Displays a summary of a message for the list view.
Scheduling & System Intents
K-9 currently uses the
AlarmManager API for scheduling tasks related to fetching email
K9AlarmManagerprovides a slight abstraction over the
CoreReceiverare responsible for receiving
Intents from Android
BootReceiverschedules and receives scheduled intents with the
Intents to the BootReceiver to reschedule polls and refresh push receipt connections
- To create IMAP PUSH email connections, the
MailServiceservice starts the
PushServiceand then instructs the
MessagingControllerto start pushing
PushServicedoes very little. It’s purpose is to ensure that K-9 remains running while push connections are established
PollServiceperforms a poll on the given account - again done as a service to ensure K-9 remains running during this period, regardless of whether UI is visible.
Intents to refresh pushing and polling as demanded by the remote application.
SleepServiceis used to delay push reconnection on error.
SCHEDULE_INTENT- Indicates an application wants the given
ALARMED_INTENTextra to occur
AT_TIMEin the future
FIRE_INTENT- Dispatched by the
K9AlarmManagerwhen a scheduled
CANCEL_INTENT- Cancels a previously scheduled
LocalStore has a separate
LockableDatabase which controls access to an SQLiteDatabase. Hence querying multiple accounts requires accessing separate database files. The database is stored by a StorageProvider (of which there are several types with specific support for Samsung Galaxy and HTC devices).
folders- Contains the list of folders (and caches various parameters like unread count)
messages- Contains the messages. Has fields to store useful fields like preview, text, subject. References it’s root message part’s id (
message_parts- Contains a MIME message part
threads- Stores a message_id, it’s parent message_id and root message_id.
pending_commands- The queued outstanding commands requiring processing.
- Virtual Table:
messages_fulltext- Used for searching message contents
Third Party Integration
K-9 is built on Android, as such it uses two main methods of providing an interface for external applications: