Android实现电子邮箱客户端

时间:2023-02-22 17:37:08

本文主要讲述了安卓平台上利用QQ邮箱SMTP协议,POP3协议发送与接收消息的实现

发送邮件核心代码

 import java.security.Security;
import java.util.Date;
import java.util.Properties; import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; /**
* 使用Gmail发送邮件
* @author Winter Lau
*/
public class GmailSender { public static void main(String[] args) throws AddressException, MessagingException {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
// Get a Properties object
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", "smtp.qq.com");
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.auth", "true");
final String username = "yourusername";
final String password = "yourpassword";
Session session = Session.getDefaultInstance(props, new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}}); // -- Create a new message --
Message msg = new MimeMessage(session); // -- Set the FROM and TO fields --
msg.setFrom(new InternetAddress(username + "@qq.com"));
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("yourusername@qq.com",false));
msg.setSubject("Hello");
msg.setText("How are you");
msg.setSentDate(new Date());
Transport.send(msg); System.out.println("Message sent.");
}
}

接收邮件核心代码

 import java.io.UnsupportedEncodingException;
import java.security.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility; /**
* 用于收取Gmail邮件
* @author Winter Lau
*/
public class GmailFetch { public static void main(String argv[]) throws Exception { Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; // Get a Properties object
Properties props = System.getProperties();
props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.port", "995");
props.setProperty("mail.pop3.socketFactory.port", "995"); //以下步骤跟一般的JavaMail操作相同
Session session = Session.getDefaultInstance(props,null); //请将红色部分对应替换成你的邮箱帐号和密码
URLName urln = new URLName("pop3","pop.qq.com",995,null,
"yourusername@qq.com", "yourpassword");
Store store = session.getStore(urln);
Folder inbox = null;
try {
store.connect();
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
FetchProfile profile = new FetchProfile();
profile.add(FetchProfile.Item.ENVELOPE);
Message[] messages = inbox.getMessages();
inbox.fetch(messages, profile);
System.out.println("收件箱的邮件数:" + messages.length);
for (int i = 0; i < messages.length; i++) {
//邮件发送者
String from = decodeText(messages[i].getFrom()[0].toString());
InternetAddress ia = new InternetAddress(from);
System.out.println("FROM:" + ia.getPersonal()+'('+ia.getAddress()+')');
//邮件标题
System.out.println("TITLE:" + messages[i].getSubject());
//邮件大小
System.out.println("SIZE:" + messages[i].getSize());
//邮件发送时间
System.out.println("DATE:" + messages[i].getSentDate());
}
} finally {
try {
inbox.close(false);
} catch (Exception e) {}
try {
store.close();
} catch (Exception e) {}
}
} protected static String decodeText(String text)
throws UnsupportedEncodingException {
if (text == null)
return null;
if (text.startsWith("=?GB") || text.startsWith("=?gb"))
text = MimeUtility.decodeText(text);
else
text = new String(text.getBytes("ISO8859_1"));
return text;
} }

注意,接收邮件使用java客户端时可以正常得到数据,在使用安卓的时候,就会卡在store.connect(),原因不详,无法解决

问题已解决,安卓似乎强行并不允许连接网络的操作在主线程中,将store.connnect()放到子线程中即可,不然会卡住

注意,发邮件时,要导入activation.jar,不然的话会报java.lang.noClassDefFoundError:javax.activation.DataHandler

最后完成版本

主界面

package com.zj.myemail;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener; public class MainActivity extends Activity { private ExpandableListView expendView;
private int []group_click=new int[5];
private long mExitTime=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
final MyExpendAdapter adapter=new MyExpendAdapter(); expendView=(ExpandableListView) findViewById(R.id.list);
expendView.setGroupIndicator(null); //设置默认图标不显示
expendView.setAdapter(adapter); //一级点击事件
expendView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) { group_click[groupPosition]+=1;
adapter.notifyDataSetChanged();
return false;
}
}); //二级点击事件
expendView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
//可在这里做点击事件
if(groupPosition==0&&childPosition==1){
/*AlertDialog.Builder builder=new Builder(MainActivity.this);
builder.setTitle("添加联系人"); View view=getLayoutInflater().inflate(R.layout.email_add_address, null);
final EditText name=(EditText) view.findViewById(R.id.name);
final EditText addr=(EditText) view.findViewById(R.id.address); builder.setView(view);
builder.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
insertAddress(name.getText().toString().trim(),addr.getText().toString().trim());
}
});
builder.setNegativeButton("取消", null);
builder.show();*/
}else if(groupPosition==0&&childPosition==0){
//Intent intent=new Intent(MainActivity.this, MailConstactsActivity.class);
//startActivity(intent);
}else if(groupPosition==1&&childPosition==0){
Intent intent=new Intent(MainActivity.this, MailEditActivity.class);
startActivity(intent);
}else if(groupPosition==1&&childPosition==1){
//Intent intent=new Intent(MainActivity.this, MailCaogaoxiangActivity.class);
//startActivity(intent);
}else if(groupPosition==2&&childPosition==0){
Intent intent=new Intent(MainActivity.this, MailBoxActivity.class);
intent.putExtra("TYPE", "INBOX");
intent.putExtra("status", 0);//全部
startActivity(intent);
}else if(groupPosition==2&&childPosition==1){
//Intent intent=new Intent(MainActivity.this, MailBoxActivity.class);
//intent.putExtra("TYPE", "INBOX");
//intent.putExtra("status", 1);//未读
//startActivity(intent);
}else if(groupPosition==2&&childPosition==2){
//Intent intent=new Intent(MainActivity.this, MailBoxActivity.class);
//intent.putExtra("TYPE", "INBOX");
//intent.putExtra("status", 2);//已读
//startActivity(intent);
}
adapter.notifyDataSetChanged();
return false;
}
}); } /**
* 添加联系人
*/
/*private void insertAddress(String user,String address){
if(user==null){
Toast.makeText(HomeActivity.this, "用户名不能为空", Toast.LENGTH_SHORT).show();
}else{
if(!EmailFormatUtil.emailFormat(address)){
Toast.makeText(HomeActivity.this, "邮箱格式不正确", Toast.LENGTH_SHORT).show();
}else{
Uri uri=Uri.parse("content://com.emailconstantprovider");
ContentValues values=new ContentValues();
values.put("mailfrom", MyApplication.info.getUserName());
values.put("name", user);
values.put("address", address);
getContentResolver().insert(uri, values); Toast.makeText(HomeActivity.this, "添加数据成功", Toast.LENGTH_SHORT).show();
}
} }*/ /**
* 适配器
* @author Administrator
*
*/
private class MyExpendAdapter extends BaseExpandableListAdapter{ /**
* pic state
*/
//int []group_state=new int[]{R.drawable.group_right,R.drawable.group_down}; /**
* group title
*/
String []group_title=new String[]{"联系人","写邮件","收件箱"}; /**
* child text
*/
String [][] child_text=new String [][]{
{"联系人列表","添加联系人"},
{"新邮件","草稿箱"},
{"全部邮件","未读邮件","已读邮件"},};
int [][] child_icons=new int[][]{
{R.drawable.listlianxiren,R.drawable.tianjia},
{R.drawable.xieyoujian,R.drawable.caogaoxiang},
{R.drawable.all,R.drawable.notread,R.drawable.hasread},
}; /**
* 获取一级标签中二级标签的内容
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
return child_text[groupPosition][childPosition];
} /**
* 获取二级标签ID
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
/**
* 对一级标签下的二级标签进行设置
*/
@SuppressLint("SimpleDateFormat")
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
convertView=getLayoutInflater().inflate(R.layout.email_child, null);
TextView tv=(TextView) convertView.findViewById(R.id.tv);
tv.setText(child_text[groupPosition][childPosition]); ImageView iv=(ImageView) convertView.findViewById(R.id.child_icon);
iv.setImageResource(child_icons[groupPosition][childPosition]);
return convertView;
} /**
* 一级标签下二级标签的数量
*/
@Override
public int getChildrenCount(int groupPosition) {
return child_text[groupPosition].length;
} /**
* 获取一级标签内容
*/
@Override
public Object getGroup(int groupPosition) {
return group_title[groupPosition];
} /**
* 一级标签总数
*/
@Override
public int getGroupCount() {
return group_title.length;
} /**
* 一级标签ID
*/
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
/**
* 对一级标签进行设置
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
convertView=getLayoutInflater().inflate(R.layout.email_group, null); ImageView icon=(ImageView) convertView.findViewById(R.id.icon);
ImageView iv=(ImageView) convertView.findViewById(R.id.iv);
TextView tv=(TextView) convertView.findViewById(R.id.iv_title); iv.setImageResource(R.drawable.group_right);
tv.setText(group_title[groupPosition]); if(groupPosition==0){
icon.setImageResource(R.drawable.constants);
}else if(groupPosition==1){
icon.setImageResource(R.drawable.mailto);
}else if(groupPosition==2){
icon.setImageResource(R.drawable.mailbox);
} if(group_click[groupPosition]%2==0){
iv.setImageResource(R.drawable.group_right);
}else{
iv.setImageResource(R.drawable.group_down);
} return convertView;
}
/**
* 指定位置相应的组视图
*/
@Override
public boolean hasStableIds() {
return true;
} /**
* 当选择子节点的时候,调用该方法
*/
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
} } /**
* 返回退出系统
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
if((System.currentTimeMillis()-mExitTime)<2000){
android.os.Process.killProcess(android.os.Process.myPid());
}else{
Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
mExitTime=System.currentTimeMillis();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
}

收件箱


package com.zj.myemail; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler; import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.DialerFilter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import javax.mail.FetchProfile;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility; public class MailBoxActivity extends Activity { private ArrayList<Email> mailslist = new ArrayList<Email>();
private ArrayList<ArrayList<InputStream>> attachmentsInputStreamsList = new ArrayList<ArrayList<InputStream>>();
private String type;
private int status;
private MyAdapter myAdapter;
private ListView lv_box;
//private List<MailReceiver> mailReceivers;
private ProgressDialog dialog; private List<String> messageids;
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
dialog.dismiss(); myAdapter = new MyAdapter();
lv_box.setAdapter(myAdapter);
}; };
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState); setContentView(R.layout.email_mailbox);
initView(); } private void initView() {
lv_box = (ListView) findViewById(R.id.lv_box); dialog=new ProgressDialog(this);
dialog.setMessage("正加载");
dialog.show(); Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; // Get a Properties object
Properties props = System.getProperties();
props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.port", "995");
props.setProperty("mail.pop3.socketFactory.port", "995"); //以下步骤跟一般的JavaMail操作相同
final Session session = Session.getDefaultInstance(props,null); //请将红色部分对应替换成你的邮箱帐号和密码
final URLName urln = new URLName("pop3","pop.qq.com",995,null,
"yourusername@qq.com", "yourpassword"); new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Store store=null;
Folder inbox = null;
try { store = session.getStore(urln); Log.i("test","here1");
store.connect();
Log.i("test","here2");
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
FetchProfile profile = new FetchProfile();
profile.add(FetchProfile.Item.ENVELOPE);
Message[] messages = inbox.getMessages();
inbox.fetch(messages, profile);
Log.i("test",messages.length+"");
System.out.println("收件箱的邮件数:" + messages.length);
for (int i = 0; i < messages.length; i++) {
//邮件发送者
String from = decodeText(messages[i].getFrom()[0].toString());
InternetAddress ia = new InternetAddress(from);
System.out.println("FROM:" + ia.getPersonal()+'('+ia.getAddress()+')');
//邮件标题
System.out.println("TITLE:" + messages[i].getSubject());
//邮件大小
System.out.println("SIZE:" + messages[i].getSize());
//邮件发送时间
System.out.println("DATE:" + messages[i].getSentDate());
Email email=new Email();
email.setFrom(ia.getPersonal()+'('+ia.getAddress()+')');
email.setSubject( messages[i].getSubject());
email.setSentdata(messages[i].getSentDate()+""); mailslist.add(email); } handler.sendEmptyMessage(0);
} catch(Exception e)
{ }
finally {
try {
inbox.close(false);
} catch (Exception e) {}
try {
store.close();
} catch (Exception e) {}
}
}
}).start(); } protected static String decodeText(String text)
throws UnsupportedEncodingException {
if (text == null)
return null;
if (text.startsWith("=?GB") || text.startsWith("=?gb"))
text = MimeUtility.decodeText(text);
else
text = new String(text.getBytes("ISO8859_1"));
return text;
} /**
* 适配器
* @author Administrator
*
*/
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
return mailslist.size();
} @Override
public Object getItem(int position) {
return mailslist.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(MailBoxActivity.this).inflate(R.layout.email_mailbox_item, null); TextView tv_from = (TextView) convertView.findViewById(R.id.tv_from);
tv_from.setText(mailslist.get(position).getFrom()); TextView tv_sentdate = (TextView) convertView.findViewById(R.id.tv_sentdate);
tv_sentdate.setText(mailslist.get(position).getSentdata()); TextView tv_subject = (TextView) convertView.findViewById(R.id.tv_subject);
tv_subject.setText(mailslist.get(position).getSubject()); return convertView;
} } }

发送邮件

package com.zj.myemail;

import java.security.Security;
import java.util.Date;
import java.util.Properties; import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast; public class MailEditActivity extends Activity {
private EditText mail_to;
private EditText mail_from;
private EditText mail_topic;
private EditText mail_content; private Button send;
private ImageButton add_lianxiren;
private ImageButton attachment; private int mailid = -1; private static final int SUCCESS = 1;
private static final int FAILED = -1;
private boolean isCaogaoxiang = true;
private ProgressDialog dialog; Handler handler = new Handler() { public void handleMessage(android.os.Message msg) {
dialog.dismiss();
Toast.makeText(MailEditActivity.this, "发送成功", 0).show();
};
}; @Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.email_writer);
init();
} /**
* 初始化
*/
private void init() {
mail_to = (EditText) findViewById(R.id.mail_to);
mail_from = (EditText) findViewById(R.id.mail_from);
mail_topic = (EditText) findViewById(R.id.mail_topic);
mail_content = (EditText) findViewById(R.id.content);
send = (Button) findViewById(R.id.send);
attachment = (ImageButton) findViewById(R.id.add_att);
add_lianxiren = (ImageButton) findViewById(R.id.add_lianxiren); mail_from.setText("yourusername@qq.com");
mail_to.setText("yourusername@qq.com"); } public void mySend(View view) {
Toast.makeText(getApplicationContext(), "正在发送", 0).show();
sendMail();
} /**
* 设置邮件数据
*/
private void sendMail() { dialog = new ProgressDialog(this);
dialog.setMessage("正在发送");
dialog.show();
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
try {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
// Get a Properties object
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", "smtp.qq.com");
props.setProperty("mail.smtp.socketFactory.class",
SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback",
"false");
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.auth", "true");
final String username = "yourusername";
final String password = "yourpassword";
Session session = Session.getDefaultInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username,
password);
}
}); // -- Create a new message --
final Message msg = new MimeMessage(session); // -- Set the FROM and TO fields --
msg.setFrom(new InternetAddress(username + "@qq.com")); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(mail_to.getText().toString()));
msg.setSubject(mail_topic.getText().toString());
msg.setText(mail_content.getText().toString());
msg.setSentDate(new Date()); Transport.send(msg);
handler.sendEmptyMessage(0);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}).start(); System.out.println("Message sent."); } /**
* /** 返回
*
* @param v
*/
public void back(View v) {
finish(); } /**
* 返回按钮
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
finish();
return super.onKeyDown(keyCode, event);
} }

完成,以下为另外的例子

详细实例

准备过程

  1. 下载jar包
  2. 在QQ邮箱中手动开启SMTP,POP3

参考链接

QQ邮箱开启SMTP服务的步骤_百度经验

实现

登陆与验证

登陆界面,主要是两个输入框

package com.email;
import com.email.app.MyApplication;
import com.email.utils.EmailFormatUtil;
import com.email.utils.HttpUtil; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
public class LoginActivity extends Activity implements TextWatcher, OnClickListener{
private EditText emailAddress;
private EditText password;
private Button clearAddress;
private Button emailLogin;
private ProgressDialog dialog;
private SharedPreferences sp;
private CheckBox cb_remenber;
private CheckBox cb_autologin;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(MyApplication.session==null){
dialog.dismiss();
Toast.makeText(LoginActivity.this, "账号或密码错误", Toast.LENGTH_SHORT).show();
}else{
dialog.dismiss();
Intent intent=new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
finish();
//Toast.makeText(LoginActivity.this, "登入成功", Toast.LENGTH_SHORT).show();
}
super.handleMessage(msg);
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.email_login);
sp=getSharedPreferences("config", Context.MODE_APPEND);
initView();
isRemenberPwd();
} /**
* 初始化数据
*/
private void initView(){
emailAddress=(EditText) findViewById(R.id.emailAddress);
password=(EditText) findViewById(R.id.password);
clearAddress=(Button) findViewById(R.id.clear_address);
emailLogin=(Button) findViewById(R.id.login_btn);
cb_remenber=(CheckBox) findViewById(R.id.remenberPassword);
cb_autologin=(CheckBox) findViewById(R.id.autoLogin); clearAddress.setOnClickListener(this);
emailAddress.addTextChangedListener(this);
emailLogin.setOnClickListener(this); cb_remenber.setOnClickListener(this);
cb_autologin.setOnClickListener(this); } @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.clear_address:
emailAddress.setText("");
break;
case R.id.login_btn:
loginEmail();
break;
case R.id.remenberPassword:
remenberPwd();
break;
case R.id.autoLogin:
break;
}
} /**
* 是否记住密码
*/
private void isRemenberPwd(){
boolean isRbPwd=sp.getBoolean("isRbPwd", false);
if(isRbPwd){
String addr=sp.getString("address", "");
String pwd=sp.getString("password", "");
emailAddress.setText(addr);
password.setText(pwd);
cb_remenber.setChecked(true);
}
} /**
* 记住密码
*/
private void remenberPwd(){
boolean isRbPwd=sp.getBoolean("isRbPwd", false);
if(isRbPwd){
sp.edit().putBoolean("isRbPwd", false).commit();
cb_remenber.setChecked(false);
}else{
sp.edit().putBoolean("isRbPwd", true).commit();
sp.edit().putString("address", emailAddress.getText().toString().trim()).commit();
sp.edit().putString("password", password.getText().toString().trim()).commit();
cb_remenber.setChecked(true); }
} /**
* 登入邮箱
*/
private void loginEmail(){
String address=emailAddress.getText().toString().trim();
String pwd=password.getText().toString().trim();
if(TextUtils.isEmpty(address)){
Toast.makeText(LoginActivity.this, "地址不能为空", Toast.LENGTH_SHORT).show();
return;
}else{
if(TextUtils.isEmpty(pwd)){
Toast.makeText(LoginActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
return;
}
}
/**
* 校验邮箱格式
*/
if(!EmailFormatUtil.emailFormat(address)){
Toast.makeText(LoginActivity.this, "邮箱格式不正确", Toast.LENGTH_SHORT).show();
}else{
String host="smtp."+address.substring(address.lastIndexOf("@")+1);
MyApplication.info.setMailServerHost(host);
MyApplication.info.setMailServerPort("465");
MyApplication.info.setUserName(address);
MyApplication.info.setPassword(pwd);
MyApplication.info.setValidate(true); /**
* 进度条
*/
dialog=new ProgressDialog(LoginActivity.this);
dialog.setMessage("正在登入,请稍后");
dialog.show(); /**
* 访问网络
*/
new Thread(){
@Override
public void run() {
//登入操作
HttpUtil util=new HttpUtil();
MyApplication.session=util.login();
Message message=handler.obtainMessage();
message.sendToTarget();
} }.start();
}
} /**
* 文本监听事件
*
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!TextUtils.isEmpty(s)){
clearAddress.setVisibility(View.VISIBLE);
}else{
clearAddress.setVisibility(View.INVISIBLE);
} } @Override
public void afterTextChanged(Editable s) { } @Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) { } }

点击登陆会跳转到此处,HttpUtils如下 ,主要包括验证是否成功登陆与发送消息的方法,

其中创建了一个密码验证器,并且根据邮件会话属性和密码验证器构造一个发送邮件的session

package com.email.utils;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List; import javax.activation.CommandMap;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import com.email.app.MyApplication;
import com.email.bean.Attachment;
import com.email.bean.MailInfo;
import com.email.bean.MyAuthenticator;
public class HttpUtil {
/**
* 连接邮箱
* @param info
* @return
*/
public Session login(){
//连接服务器
Session session=isLoginRight(MyApplication.info);
return session;
} /**
* 登入操作
* @param info
* @return
*/
private Session isLoginRight(MailInfo info) {
//判断是否要登入验证
MyAuthenticator authenticator=null;
if(info.isValidate()){
//创建一个密码验证器
authenticator=new MyAuthenticator(info.getUserName(), info.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession=Session.getDefaultInstance(info.getProperties(), authenticator);
try {
Transport transport=sendMailSession.getTransport("smtp");
transport.connect(info.getMailServerHost(), info.getUserName(), info.getPassword());
} catch (MessagingException e) {
e.printStackTrace();
return null;
}
return sendMailSession;
} /**
* 以文本格式发送邮件
*
* @param <T>
*
* @param mailInfo
* 待发送的邮件的信息
*/
public boolean sendTextMail(MailInfo mailInfo, Session sendMailSession) {
// 判断是否需要身份认证
try {
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address address=new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(address);
// 创建邮件的接收者地址,并设置到邮件消息中
Address[] tos = null;
String[] receivers = mailInfo.getReceivers();
if (receivers != null) {
// 为每个邮件接收者创建一个地址
tos = new InternetAddress[receivers.length];
for (int i = 0; i < receivers.length; i++) {
tos[i] = new InternetAddress(receivers[i]);
}
} else {
return false;
}
// Message.RecipientType.TO属性表示接收者的类型为TO
mailMessage.setRecipients(Message.RecipientType.TO, tos);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// 设置邮件消息的主要内容
String mailContent = mailInfo.getContent(); Multipart mm = new MimeMultipart();// 新建一个MimeMultipart对象用来存放多个BodyPart对象
// 设置信件文本内容
BodyPart mdp = new MimeBodyPart();// 新建一个存放信件内容的BodyPart对象
mdp.setContent(mailContent, "text/html;charset=gb2312");// 给BodyPart对象设置内容和格式/编码方式
mm.addBodyPart(mdp);// 将含有信件内容的BodyPart加入到MimeMultipart对象中 Attachment affInfos;
FileDataSource fds1;
List<Attachment> list = mailInfo.getAttachmentInfos();
for (int i = 0; i < list.size(); i++) {
affInfos = list.get(i);
fds1 = new FileDataSource(affInfos.getFilePath());
mdp = new MimeBodyPart();
mdp.setDataHandler(new DataHandler(fds1));
try {
mdp.setFileName(MimeUtility.encodeText(fds1.getName()));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mm.addBodyPart(mdp);
}
mailMessage.setContent(mm);
mailMessage.saveChanges(); // 设置邮件支持多种格式
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mc); // 发送邮件
Transport.send(mailMessage);
return true;
} catch (MessagingException ex) {
ex.printStackTrace();
}
return false;
}
}

HttpUtils中用到了MailInfo中一些属性,MailInfo是邮件基本信息javabean,其中配置了邮件会话属性,和其他一些属性,内容如下

由于现在是SSL方法验证,似乎都要加上

p.put("mail.smtp.starttls.enable", "true");
//需要加上
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.socketFactory.port", "465");

刚开始没加就出错了

package com.email.bean;

import java.io.Serializable;
import java.util.List;
import java.util.Properties; /**
* 邮件的基本信息
* @author Administrator
*
*/
public class MailInfo implements Serializable {
private static final long serialVersionUID = 1L;
// 发送邮件的服务器的IP和端口
private String mailServerHost;
private String mailServerPort = "465";
// 登陆邮件发送服务器的用户名和密码
private String userName;
private String password;
// 是否需要身份验证
private boolean validate = false;
// 邮件发送者的地址
private String fromAddress;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
// 邮件附件的路径
private List<Attachment> attachmentInfos;
// 邮件的接收者,可以有多个
private String[] receivers; /**
* 获得邮件会话属性
*/
public Properties getProperties() {
Properties p = new Properties();
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
p.put("mail.smtp.auth", validate ? "true" : "false"); p.put("mail.smtp.starttls.enable", "true");
//需要加上
p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
p.put("mail.smtp.socketFactory.port", "465"); return p;
} public String[] getReceivers() {
return receivers;
} public void setReceivers(String[] receivers) {
this.receivers = receivers;
} public String getMailServerHost() {
return mailServerHost;
} public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
} public String getMailServerPort() {
return mailServerPort;
} public void setMailServerPort(String mailServerPort) {
this.mailServerPort = mailServerPort;
} public boolean isValidate() {
return validate;
} public void setValidate(boolean validate) {
this.validate = validate;
} public List<Attachment> getAttachmentInfos() {
return attachmentInfos;
} public void setAttachmentInfos(List<Attachment> attachmentInfos) {
this.attachmentInfos = attachmentInfos;
} public String getFromAddress() {
return fromAddress;
} public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getSubject() {
return subject;
} public void setSubject(String subject) {
this.subject = subject;
} public String getContent() {
return content;
} public void setContent(String textContent) {
this.content = textContent;
}
}

session是Application中声明的静态全局变量,info也是

package com.email.app;
import java.io.InputStream;
import java.util.ArrayList; import javax.mail.Session;
import javax.mail.Store; import com.email.bean.MailInfo; import android.app.Application; public class MyApplication extends Application {
public static Session session = null;
public static Store getStore() {
return store;
} public static void setStore(Store store) {
MyApplication.store = store;
} public static MailInfo info=new MailInfo(); private static Store store;
private ArrayList<InputStream> attachmentsInputStreams; public ArrayList<InputStream> getAttachmentsInputStreams() {
return attachmentsInputStreams;
} public void setAttachmentsInputStreams(ArrayList<InputStream> attachmentsInputStreams) {
this.attachmentsInputStreams = attachmentsInputStreams;
} }

参考链接:

JavaMail - qw765811529的专栏 - 博客频道 - CSDN.NET

接收邮箱信息

待续

效果如下

Android实现电子邮箱客户端

Android实现电子邮箱客户端

Android实现电子邮箱客户端的更多相关文章

  1. Kindle 推送教程:教你用电子邮箱推送电子书(Kindle伴侣)

    Kindle 推送是什么意思?如何通过电子邮件附件推送?或许刚刚接触 Kindle 的朋友对这个概念不是很清楚,其实所谓 Kindle 推送是指亚马逊提供的一个"Kindle 个人文档服务& ...

  2. YoMail 邮箱客户端的社会化之路,起于邮箱,不止于邮件

    你还记不记得上一次用邮箱处理私人事务是什么时候?从什么时候开始邮箱于你而言,唯一功能沦为了收取各种网站的验证信息? 电子邮件实际上非常适合于工作上使用,比起其他通信工具,或者社会化媒体,电子邮件在工作 ...

  3. &lbrack;转&rsqb;Kindle 推送教程:教你用电子邮箱推送电子书

    Kindle 推送是什么意思?如何通过电子邮件附件推送?或许刚刚接触 Kindle 的朋友对这个概念不是很清楚,其实所谓 Kindle 推送是指亚马逊提供的一个“Kindle 个人文档服务”,我们只需 ...

  4. 【Python】【电子邮箱】

    #[[电子邮件]]'''Email的历史比Web还要久远,直到现在,Email也是互联网上应用非常广泛的服务. 几乎所有的编程语言都支持发送和接收电子邮件,但是,先等等,在我们开始编写代码之前,有必要 ...

  5. Outlook 2010中263邮箱客户端设置

    Outlook 2010中263邮箱客户端设置 1.首次添加电子邮箱账户:打开outlook,在账户设置和服务中分别选择:“手动配置服务器设置或其他服务器类型”,“Internet电子邮件” 2.在i ...

  6. Android版的菜谱客户端应用源码完整版

    Android版的菜谱客户端应用源码完整版,这个文章是从安卓教程网转载过来的,不是本人的原创,希望能够帮到大家的学习吧. <ignore_js_op> 152936qc7jdnv6vo0c ...

  7. 2015第37周二foxmail邮箱客户端迁移

    foxmail7.0邮箱客户端迁移风波浪费我下午不少时间,不知为何做完foxmail客户端在卡的时候我将其强制关闭,然后将整个邮箱目录拷贝到一台新电脑上,运行客户端居然我要新建账户(账户信息丢失),将 ...

  8. Android手机SSH Client客户端推荐JuiceSSH

    Windows上建立ssh服务器 参见: http://www.cnblogs.com/xred/archive/2012/04/21/2461627.html Android手机SSH Client ...

  9. Kindle 推送教程:教你用电子邮箱推送电子书

    Kindle 推送是什么意思?如何通过电子邮件附件推送?或许刚刚接触 Kindle 的朋友对这个概念不是很清楚,其实所谓 Kindle 推送是指亚马逊提供的一个"Kindle 个人文档服务& ...

随机推荐

  1. Ajax工作流程

    Ajax通过XMLHttpRequest对象实现异步方式在后台发送发送请求. 主要有以下四个步骤: (1)初始化XMLHttpRequest对象.不同浏览器的差异,需要我们创建一个跨浏览器的对象,并判 ...

  2. myeclipse2014

    myeclipse 2014-GA offline  迅雷下载  http://downloads.myeclipseide.com/downloads/products/eworkbench/201 ...

  3. Xcode打印frame id

    开启 打开终端输入三条命令: . touch ~/.lldbinit . echo display @import UIKit >> ~/.lldbinit . echo target s ...

  4. Kafka 分区备份实战

    1.概述 在 Kafka 集群中,我们可以对每个 Topic 进行一个或是多个分区,并为该 Topic 指定备份数.这部分元数据信息都是存放在 Zookeeper 上,我们可以使用 zkCli 客户端 ...

  5. CodeForces 732B Cormen — The Best Friend Of a Man &lpar;贪心&rpar;

    题意:给定n和k表示,狗要在任意连续两天散步次数要至少为k,然后就是n个数,表示每天的时间,让你增加最少次数使得这个条件成立. 析:贪心,策略是从开始到最后暴力,每次和前面一个相比,如果相加不够k,那 ...

  6. Shell脚本编程入门(一)

    最近在学shell,记录一下. if语句的使用: 1.判断两个参数大小 #!/bin/sh #a test about if statement a=10 b=20 if [ $a -eq $b ]; ...

  7. 2-sat-总结&plus;例题

    https://www.cnblogs.com/31415926535x/p/10644419.html 从寒假就开始准备学2sat,,然后当时了解了一下模板就溜了,,,一直到上个星期,,三月底才好好 ...

  8. 【bzoj1044】木棍分割

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  9. 战争迷雾Fog Of War

    参考:https://forums.unrealengine.com/community/community-content-tools-and-tutorials/26436-tutorial-fo ...

  10. 区分IE8&sol;IE7&sol;IE6及其他浏览器-CSS &OpenCurlyDoubleQuote;&bsol;9″

    区分IE8/IE7/IE6及其他浏览器-CSS “\9″ 原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com] by zhangxinxu from h ...