How to enable password recovery functionality through email in Android applications involves several key steps including server-side email configuration and client-side implementation.
Configuring Email Services
To implement email-based password recovery, you first need to configure you're email service provider. For instance, if using QQ email, enable IMAP access in your account settings. This allows third-party clients like Foxmail to connect and manage emails programmatically.
Email Utility Class Implementation
The follwoing Java class demonstrates how to send an email using SMTP with SSL encryption:
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public class EmailSender {
private static final String SENDER_EMAIL = "your_email@qq.com";
private static final String SENDER_PASSWORD = "your_app_password";
private static final String SMTP_HOST = "smtp.qq.com";
public void sendRecoveryEmail(String recipient, String password) {
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", SMTP_HOST);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.socketFactory.port", "465");
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(SENDER_EMAIL, SENDER_PASSWORD);
}
});
try {
Message message = createMessage(session, SENDER_EMAIL, recipient, password);
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
private Message createMessage(Session session, String sender, String recipient, String password)
throws MessagingException {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(sender, "System", "UTF-8"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject("Password Recovery", "UTF-8");
message.setText("Your password is: " + password + "\nPlease change it immediately after login.");
return message;
}
}
Server-Side Servlet Implementation
The servlet handles requests for password recovery:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import net.sf.json.JSONObject;
public class PasswordRecoveryServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String email = request.getParameter("email");
int verification = verifyCredentials(username, email);
Map<String, String> result = new HashMap<>();
JSONObject jsonResponse = new JSONObject();
if (verification == -1) {
result.put("status", "user_not_found");
} else if (verification == 0) {
result.put("status", "email_mismatch");
} else {
result.put("status", "success");
// Send email with password
EmailSender sender = new EmailSender();
sender.sendRecoveryEmail(email, getUserPassword(username));
}
jsonResponse.put("data", result);
response.getWriter().write(jsonResponse.toString());
}
private int verifyCredentials(String username, String email) {
// Check if user exists and email matches
return UserDAO.validateUser(username, email) ? 1 : (UserDAO.userExists(username) ? 0 : -1);
}
private String getUserPassword(String username) {
return UserDAO.getUserByUsername(username).getPassword();
}
}
Android Client Implementation
The Android activity implements the UI and network communication:
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import com.android.volley.*;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class PasswordRecoveryActivity extends AppCompatActivity {
private EditText usernameField, emailField;
private RequestQueue requestQueue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_password_recovery);
requestQueue = Volley.newRequestQueue(this);
usernameField = findViewById(R.id.username_input);
emailField = findViewById(R.id.email_input);
Button submitButton = findViewById(R.id.submit_button);
submitButton.setOnClickListener(v -> {
String username = usernameField.getText().toString().trim();
String email = emailField.getText().toString().trim();
// Encrypt credentials before sending
String encryptedUsername = encryptWithPublicKey(username);
String encryptedEmail = encryptWithPublicKey(email);
sendRecoveryRequest(encryptedUsername, encryptedEmail);
});
}
private void sendRecoveryRequest(String username, String email) {
String url = "http://yourserver.com/recovery";
StringRequest request = new StringRequest(Request.Method.POST, url,
response -> {
try {
JSONObject jsonObject = new JSONObject(response);
String status = jsonObject.getJSONObject("data").getString("status");
if ("user_not_found".equals(status)) {
Toast.makeText(this, "User not found", Toast.LENGTH_SHORT).show();
} else if ("email_mismatch".equals(status)) {
Toast.makeText(this, "Email does not match", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Password sent to email", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
},
error -> Toast.makeText(this, "Network error", Toast.LENGTH_SHORT).show()) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
params.put("email", email);
return params;
}
};
requestQueue.add(request);
}
}
Layout File
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/username_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter username" />
<EditText
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter registered email" />
<Button
android:id="@+id/submit_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recover Password" />
</LinearLayout>