Mobile application development often requires the implementation of feedback functionality, and sending an email is one of the most popular scenarios. In the environment Android Studio this process does not come down to one button, but requires setting up network protocols and working with external libraries. Integrating an email client allows users to report bugs or leave feedback without leaving the interface of your product.
There are two main approaches to solving this problem: using a standard Intent to launch a system email application or implementing a full one SMTP client directly into the app code. The first option is easier to implement, but depends on the presence of an installed mailer on the user's device. The second method provides complete autonomy, allowing you to send messages in the background, but requires more careful configuration of security and access rights.
In this article we will analyze both methods in detail, paying special attention to working with the library JavaMail API, which is the de facto standard for such tasks in the Java and Android ecosystem. You will learn how to properly configure a manifest, handle asynchronous operations, and avoid common errors when authorizing on mail servers.
Preparing a project and setting up a manifest
Before writing code, you need to provide the application with the necessary privileges to work with the network. Without the appropriate permissions, the operating system Android will block any attempts to establish a connection with the outside world. Open the file AndroidManifest.xml at the root of your project and add the following lines inside the tag manifestbut before the tag application.
The key element here is Internet access permission. Also, if you plan to check the network status before sending, it is useful to add permission to access network status information. This will allow your application to respond correctly when there is no connection, rather than simply throwing a connection error.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
In addition to access rights, it is important to consider the platform's security policies. Starting from version Android 9 (API level 28), unencrypted HTTP traffic is prohibited by default. Since many older SMTP servers may use unsecured ports, you may need to configure Network Security Configuration. This is done through a separate XML resource file, where you can explicitly allow traffic for specific domains or relax the requirements for debugging purposes.
โ ๏ธ Attention: Never store passwords for real mailboxes in the application source code in clear text. If published on Google Play, such an application will be rejected or deleted, and the developer's account may be blocked for violating security policies. Use special application passwords or server-side proxy processing.
โ๏ธ Preparing for mail integration
Method via Intent: launching an external email client
The easiest and most reliable way to send a letter is to delegate this task to one already installed on the userโs device mail client. This method does not require heavy libraries and works stably on all versions Android. The implementation uses a class Intent with an action ACTION_SENDTO and a URI scheme mailto:.
When using this approach, you form an intent object, fill in its recipient, subject and message body fields, and then launch the activity. The system will automatically prompt the user to select an application from the list of installed ones (Gmail, Outlook, Yandex.Mail and others). This solution is ideal for feedback forms where user participation in the sending process is desirable.
However, it is worth remembering that this method does not guarantee that the letter will actually be sent. You just transfer the data to the external application, and the user must click the "Submit" button. In addition, if no email client is configured on the device, attempting to launch Intent may crash the application if the exception is not handled.
Intent intent = new Intent(Intent.ACTION_SENDTO);intent.setData(Uri.parse("mailto:")); // mail applications only
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"support@example.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Error report");
intent.putExtra(Intent.EXTRA_TEXT, "Problem description...");
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
โ ๏ธ Attention: Always check for an application that can handle your
Intent, using theresolveActivitymethod. An attempt to callstartActivitywithout this check on a device without mail clients will throw an exception.ActivityNotFoundException.
Use the "mailto:" scheme in setData to filter out instant messengers and social networks. If you simply use ACTION_SEND, the system will offer to send a text via WhatsApp or Telegram, which may be undesirable.
Integration of the JavaMail API library
To implement background sending of letters without user interaction, you must use the library JavaMail API. In projects Android Studio it is most convenient to include dependencies through the build system Gradle. Add the required line to the file build.gradle (app module) in the dependencies block.
Modern versions of the library can be heavy for mobile devices, so they often use lightweight forks or specific artifacts adapted for Android. After adding the dependency, be sure to synchronize the project (Sync Project with Gradle Files) so that the library files are loaded into the local cache.
- ๐ฆ Main library: Provides base classes for working with the SMTP, IMAP and POP3 protocols.
- ๐ Security module: Requires SSL/TLS activation encryption for secure data transfer.
- โ๏ธ Property configuration: Required to configure the host, port and authentication methods.
It is important to note that working with mail protocols is a network operation. Performing such tasks in the main thread (UI Thread) will block the interface and throw an exception NetworkOnMainThreadException. Therefore, all sending logic must be placed in a separate thread, using Thread, AsyncTask (although it is outdated) or modern coroutines Kotlin.
Alternative libraries
In addition to classic JavaMail, there are lighter libraries such as Simple Java Mail or Apache Commons Email, which can simplify the code, but require careful checking of compatibility with a specific version of Android SDK.
Configuring SMTP properties and authorization
The central element of the configuration is the object Properties, in which the connection parameters with the mail server are set. You need to specify the SMTP server host (for example smtp.gmail.com), port (usually 587 for TLS or 465 for SSL) and enable authentication. Without these settings, the server will reject the connection.
Particular attention should be paid to the encryption settings. Modern email providers, such as Gmail or Yandex, require the use of a secure connection. Parameter mail.smtp.starttls.enable must be set to trueto initiate an upgrade to a secure channel after initial contact has been established.
| Parameter | Value for Gmail | Description |
|---|---|---|
mail.smtp.host |
smtp.gmail.com | SMTP server address |
mail.smtp.port |
587 | Port for TLS connection |
mail.smtp.auth |
true | Is authentication required |
mail.smtp.starttls.enable |
true | Enable STARTTLS encryption |
For authorization, an object is created Sessionto which the interface implementation is passed Authenticator. In the method getPasswordAuthentication you return the login and password. Here it is critical to use not the main account password, but a specially generated โApplication Passwordโ if two-factor authentication is enabled.
โ ๏ธ Attention: The interfaces and security rules of email services (Gmail, Mail.ru, Yandex) are regularly updated. What worked yesterday may not work tomorrow due to changes in access policy. Always check the latest requirements for SMTP connections in the official documentation of your mail provider before publishing the application.
Creating and sending a message
After setting up the session, the stage of creating the letter itself begins. For this purpose, the class MimeMessageis used, the constructor of which accepts the previously created session. In this object you set the sender (setFrom), recipient (setRecipients), subject and content of the message.
The body of the letter can be either plain text or HTML markup. To send HTML content, you must set the content type to text/html. This allows you to format the text, add links and even small images, making the letter more presentable for the recipient.
MimeMessage message = new MimeMessage(session);message.setFrom(new InternetAddress("from@example.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("to@example.com"));
message.setSubject("Subject of the letter");
message.setText("Message text", "utf-8", "html");
Transport.send(message);
Direct sending is carried out through a static method Transport.send() or through creating an instance Transport and calling the method connect() followed sendMessage(). The second option is preferable if you need to send a series of letters within one connection, as this saves resources on establishing a handshake with the server for each message.
Use the "utf-8" encoding when setting the message text to avoid problems with displaying Cyrillic and special characters in the letter to the recipient.
Error handling and asynchrony
Network operations are unpredictable: the server may be unavailable, the password may be incorrect, and the Internet may go down at the most inopportune moment. Therefore, the entire block of code responsible for sending must be wrapped in a try-catchconstruct. It is necessary to catch specific exceptions, such as MessagingException, AuthenticationFailedException and UnknownHostException.
In the block catch you should not only output an error to the log, but also inform the user about the failure, if this is appropriate in the application logic. However, this must be done carefully so as not to reveal technical details of the server's operation that could be used by attackers. It is enough to inform that โsending failed, check the connection.โ
- ๐ซ AuthenticationFailedException: Incorrect login or password (or application password).
- ๐ UnknownHostException: Problems with DNS or lack of Internet.
- ๐ SSLHandshakeException: Certificate error or mismatch of encryption protocols.
To manage asynchrony in modern Android, it is best to Kotlin Coroutines with a dispatcher Dispatchers.IO. This allows you to write linear code that runs on a background thread and the result is safely returned to the main thread to update the interface. Avoid outdated approaches that make your code more difficult to maintain.
How to bypass Gmail's "untrusted app" blocking?
Google blocks SMTP login for applications that use only a login and password unless two-factor authentication is enabled. Solution: Enable 2FA in your Google account settings and create an โApp Passwordโ in the security section. Use this 16-digit code instead of a regular password in the application code.
Is it possible to send an email without access to the Internet?
No, the SMTP protocol requires an active network connection to transfer data to the mail server. However, you can save the letter to a local database or file when there is no network and implement a queue mechanism that will try to send the accumulated letters when the connection is restored.
Why does the letter end up as spam?
Emails sent directly from a mobile device are often flagged by spam filters due to the lack of correct SPF and DKIM records in the sender's domain. For mass mailing or critical notifications, it is better to use specialized services (SendGrid, Amazon SES) through their API, rather than direct SMTP.
Which port to use: 465 or 587?
Port 465 was historically used for SMTPS (SSL), but has been officially reassigned. The current standard is port 587, using the STARTTLS command to upgrade the connection to a secure one. Most providers recommend 587, although 465 is still widely supported.