Android实现电子邮箱客户端

本文主要讲述了安卓平台上利用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;@Overrideprotected 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() {@Overridepublic boolean onGroupClick(ExpandableListView parent, View v,int groupPosition, long id) {group_click[groupPosition]+=1;adapter.notifyDataSetChanged();return false;}});//二级点击事件expendView.setOnChildClickListener(new OnChildClickListener() { @Overridepublic 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() {@Overridepublic 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},};/*** 获取一级标签中二级标签的内容*/@Overridepublic Object getChild(int groupPosition, int childPosition) {return child_text[groupPosition][childPosition];}/*** 获取二级标签ID*/@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}/*** 对一级标签下的二级标签进行设置*/@SuppressLint("SimpleDateFormat")@Overridepublic 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;}/*** 一级标签下二级标签的数量*/@Overridepublic int getChildrenCount(int groupPosition) {return child_text[groupPosition].length;}/*** 获取一级标签内容*/@Overridepublic Object getGroup(int groupPosition) {return group_title[groupPosition];}/*** 一级标签总数*/@Overridepublic int getGroupCount() {return group_title.length;}/*** 一级标签ID*/@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}/*** 对一级标签进行设置*/@Overridepublic 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;}/*** 指定位置相应的组视图*/@Overridepublic boolean hasStableIds() {return true;}/***  当选择子节点的时候,调用该方法*/@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return true;}}/*** 返回退出系统*/@Overridepublic 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);};};@Overrideprotected 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() {@Overridepublic void run() {// TODO Auto-generated method stubStore 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 {@Overridepublic int getCount() {return mailslist.size();}@Overridepublic Object getItem(int position) {return mailslist.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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();};};@Overrideprotected 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() {@Overridepublic void run() {// TODO Auto-generated method stubtry {Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";// Get a Properties objectProperties 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 blocke.printStackTrace();}}}).start();System.out.println("Message sent.");}/*** /** 返回* * @param v*/public void back(View v) {finish();}/*** 返回按钮*/@Overridepublic 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(){@Overridepublic 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);}};@Overrideprotected 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);}@Overridepublic 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(){@Overridepublic void run() {     //登入操作HttpUtil util=new HttpUtil();MyApplication.session=util.login();Message message=handler.obtainMessage();message.sendToTarget();}}.start();}}/*** 文本监听事件* */@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {if(!TextUtils.isEmpty(s)){clearAddress.setVisibility(View.VISIBLE);}else{clearAddress.setVisibility(View.INVISIBLE);}}@Overridepublic void afterTextChanged(Editable s) {}@Overridepublic 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());}// 根据邮件会话属性和密码验证器构造一个发送邮件的sessionSession 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属性表示接收者的类型为TOmailMessage.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

接收邮箱信息

待续

效果如下

这里写图片描述

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌AI涉足艺术、太空、外科手术,再强调AI七原则

来源&#xff1a;网易智能9月18日上午&#xff0c;Google在上海的2018世界AI 大会上举办了一场名为“AI触手可及”的主题论坛。在论坛上&#xff0c;Google全球副总裁、工程研究员Jay Yagnik 携Google 不同领域的研究者发表了演讲&#xff0c;重点阐述了Google AI在自家产品上的…

单个手指的手势识别

本文来自http://blog.csdn.net/hellogv/ &#xff0c;引用必须注明出处&#xff01; 本文把Aforge的运动识别与前面介绍的手写识别融合在一起&#xff0c;实现单个手指的手势识别。下图演示了本文代码运行的结果&#xff0c;图片有点大&#xff0c;请稍候。。。 我预先让程序学…

Apifox:满足你对 Api 的所有幻想

文章目录⌚️ 一、Api 管理的难点在哪&#xff1f;&#x1f4f1; 二、Apifox 是什么&#xff1f;&#x1f4bf; 三、接口设计 (接口文档)⌨️ 3.1 接口文档&#x1f4bb; 3.2 快速上手&#x1f5a8; 3.3 接口路径&#x1f4bd; 四、团队管理&#x1f4fd; 4.1 权限管理⏱ 4.2 项…

百度地图综合

本文主要包括百度地图API的综合应用&#xff0c;主要内容如下 地图图层展示&#xff0c;包括热力图与实时路况图 添加覆盖物&#xff0c;包括图片&#xff0c;文字&#xff0c;折线等地图控制&#xff0c;包括俯视&#xff0c;旋转&#xff0c;放大&#xff0c;缩小等定位&…

国内Api行业,可以内卷到什么程度?

随着移动应用以及智能设备爆发增长&#xff0c;同时越来越多的零售商、媒体、政府和金融服务公司开始公开Web API&#xff0c;API的使用越来越多。 现在&#xff0c;每日API调用量在不断飙升&#xff0c;早在2009年&#xff0c;Facebook每天API调用量就已经达到了50亿。如何能…

自动驾驶关键技术报告:惯性导航和背后的芯片大战

来源&#xff1a;智东西摘要&#xff1a;惯性导航将成为自动驾驶定位信息融合的中心。惯性导航系统由于具有的输出信息不间断、不受外界干扰的独特优势&#xff1b;同时可以将多种传感器的信息以及车身信息进行更深层次的融合&#xff0c;为决策层提供精确可靠的连续的车辆位置…

一个怪异的问题

一个怪异的问题 今天下了Linux最新版的内核(3.8.2)&#xff0c;打算在Windows下用Source Insight新建一个工程。可没想到的是用Winrar解压到一半&#xff0c;突然报错&#xff1a;无法创建 linux-3.8.2\drivers\gpu\drm\nouveau\core\subdev\i2c\aux.c我了个去&#xff0c;以前…

Python Pandas PK esProc SPL,谁才是数据预处理王者?

做数据分析和人工智能运算前常常需要大量的数据准备工作&#xff0c;也就是把各种数据源以及各种规格的数据整理成统一的格式。因为情况非常复杂多样&#xff0c;很难有某种可视化工具来完成此项工作&#xff0c;常常需要编程才能实现。 业界有很多免费的脚本语言都适合进行数…

Unity3D入门

Unity3D是一款应用广泛的3D游戏引擎&#xff0c;本文主要介绍unity3D的简单应用&#xff0c;安装过程略过。 在游戏的整个开发过程中&#xff0c;游戏界面设计占据非常重要的地位。因为游戏启动后&#xff0c;第一个映入眼帘的就是整个游戏UI界面。UI界面主要包括贴图、按钮和…

不够优秀就不要腆着脸继续占便宜——作者:杨毅

原文地址&#xff1a;http://qing.weibo.com/tj/757d5835330007vx.html 发表于&#xff1a;2011年12月12日 21:34 转发 21正视自己&#xff0c;承认能力有限&#xff0c;精益求精&#xff0c;把自己打造成优秀的人&#xff0c;实现和另外同样优秀的人“公平交换”&#xff0c;…

3D打印产业化机遇与挑战

来源&#xff1a;3D科学谷3D打印的突出特点有两个&#xff1a;免除模具以及制造成本对设计的复杂性不敏感。免除模具的特点使得3D打印适合用于产品原型、试制零件、备品备件、个性化定制、零件修复、医疗植入物、医疗导板、牙科产品、耳机产品等小批量个性化的产品。而传统制造…

分享.NET开发中经常用到的十大软件(转)

以下排名不分先后&#xff1a; 1. EditPlus&#xff1a;文字处理软件 EditPlus 是一款功能强大的文字处理软件。它可以充分的替换记事本&#xff0c;它也提供网页作家及程序设计师许多强悍的功能。支持 HTML、CSS、PHP、ASP、Perl、C/C、Java、JavaScript、VBScript 等多…

Android之ExpandableListView

ExpandableListView可以用来表现多层级的listView&#xff0c;本文主要是ExpandableListView的一个简单实现 布局文件 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"andro…

Api -- 连接世界的Super Star

文章目录&#x1f34f; 一、api 的定义&#xff1a;数据共享模式定义 4 大种类&#x1f356; 二、api 使用场景&#xff1a;互联网时代&#xff0c;api 无处不在2.1 sql 查询2.2 数据传输&#x1f364; 三、开放 api&#xff08;OpenAPI&#xff09;&#xff1a;开放双赢&#…

2018全球最强物联网公司揭晓!

来源&#xff1a;数字化企业根据Gartner预测&#xff0c; 到2020年将有超过200亿台联网设备&#xff0c;市场价值将达3000亿美元之巨。随着垂直应用上的不断细分&#xff0c;以及与AI的加速整合&#xff0c;物联网不仅将持续地变革人们的生活和工作&#xff0c;市场规模也将持续…

amr文件格式分析【转http://blog.csdn.net/dinggo/article/details/1966444】

目录1. 概述2. AMR编码方式3. AMR文件结构示范图4. AMR帧头格式分析5. 异常帧分析6. AMR帧读取算法7. 参考资料1. 概述 现在很多智能手机都支持多媒体功能&#xff0c;特别是音频和视频播放功能&#xff0c;而AMR文件格式是手机端普遍支持的音频文件…

Android之解析GML并显示

本例主要实现在APP中解析GML数据并显示 GML,地理标记语言&#xff08;外语全称&#xff1a;Geography MarkupLanguage、外语缩写&#xff1a;GML&#xff09;&#xff0c;它由开放式地理信息系统协会&#xff08;外语缩写&#xff1a;OGC&#xff09;于1999年提出&#xff0c;…

中国电子学会发布《新一代人工智能领域十大最具成长性技术展望(2018-2019年)》...

来源&#xff1a;中国电子学会当前&#xff0c;全球正在经历科技和产业高度耦合、深度迭加的新一轮变革&#xff0c;大数据的形成、理论算法的革新、计算能力的提升及网络设施的演进驱动人工智能进入新一轮创新发展高峰期&#xff0c;新技术持续获得突破性进展&#xff0c;呈现…

晓得不,中间表是这样被消灭的

目录 一、中间表的产生 1、一步算不出来 2、实时计算等待时间过长 3、多样性数据源参加计算 4、中间表难以删除 二、文件计算 三、高性能文件格式 四、易管理性 五、多数据源支持 六、集成性 七、资料 一、中间表的产生 中间表是数据库中专门存放中间计算结果的数据…

美国五大科技巨头的人工智能竞赛

来源&#xff1a;资本实验室毫无疑问&#xff0c;人工智能已经开始渗透到各行各业&#xff0c;并正在改变我们的工作方式和生活方式。2017年&#xff0c;全球与人工智能相关的资金投入总额达到152亿美元&#xff0c;比上一年增加144&#xff05;。而无论在投资&#xff0c;还是…