在android中,如何在没有用户交互的情况下发送电子邮件,而不是gmailsender?

时间:2014-08-06 06:56:54

标签: android

我正在使用下面的代码段

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
        Mail m = new Mail("someone@gmail.com", "password"); 


        public SendEmailAsyncTask() {
            if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()");
            String[] toArr = {"someone@domain.com"};
            m.setTo(toArr);
            m.setFrom("someone@domain.com");
            m.setSubject("Email from Android");
            m.setBody("Got message");
        }

我想使用someone@anydomain.com而不是someone@gmail.com。

还有什么办法可以避免在那里使用密码吗?

2 个答案:

答案 0 :(得分:0)

Android SDK可以非常轻松地从应用程序发送电子邮件,但遗憾的是,只有当您想通过内置邮件应用程序发送电子邮件时才会这样。对于大多数情况,这种方法很好,但是如果你想发送一些内容并且不希望用户输入/干预,那就不那么容易了。

在本文中,我将向您展示如何在用户不知情的情况下在后台发送电子邮件 - 应用程序将在幕后完成所有工作。

在开始之前,您需要通过以下链接下载一些文件 - 这是JavaMail API的特殊版本,专门为Android编写。

http://code.google.com/p/javamail-android/downloads/list

我将引导您浏览我编写的邮件包装器,这样可以更轻松地发送电子邮件,甚至可以添加附件,如果这是您想要做的事情。

下面是完整的包装器类,我将逐步完成 - 请记住,如果您希望这样做,您必须添加前述文件。将它们添加为外部库 - 它们需要可由Mail类访问。

    import java.util.Date; 
import java.util.Properties; 
import javax.activation.CommandMap; 
import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.activation.FileDataSource; 
import javax.activation.MailcapCommandMap; 
import javax.mail.BodyPart; 
import javax.mail.Multipart; 
import javax.mail.PasswordAuthentication; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeMultipart; 


public class Mail extends javax.mail.Authenticator { 
  private String _user; 
  private String _pass; 

  private String[] _to; 
  private String _from; 

  private String _port; 
  private String _sport; 

  private String _host; 

  private String _subject; 
  private String _body; 

  private boolean _auth; 

  private boolean _debuggable; 

  private Multipart _multipart; 


  public Mail() { 
    _host = "smtp.gmail.com"; // default smtp server 
    _port = "465"; // default smtp port 
    _sport = "465"; // default socketfactory port 

    _user = ""; // username 
    _pass = ""; // password 
    _from = ""; // email sent from 
    _subject = ""; // email subject 
    _body = ""; // email body 

    _debuggable = false; // debug mode on or off - default off 
    _auth = true; // smtp authentication - default on 

    _multipart = new MimeMultipart(); 

    // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
    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); 
  } 

  public Mail(String user, String pass) { 
    this(); 

    _user = user; 
    _pass = pass; 
  } 

  public boolean send() throws Exception { 
    Properties props = _setProperties(); 

    if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
      Session session = Session.getInstance(props, this); 

      MimeMessage msg = new MimeMessage(session); 

      msg.setFrom(new InternetAddress(_from)); 

      InternetAddress[] addressTo = new InternetAddress[_to.length]; 
      for (int i = 0; i < _to.length; i++) { 
        addressTo[i] = new InternetAddress(_to[i]); 
      } 
        msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

      msg.setSubject(_subject); 
      msg.setSentDate(new Date()); 

      // setup message body 
      BodyPart messageBodyPart = new MimeBodyPart(); 
      messageBodyPart.setText(_body); 
      _multipart.addBodyPart(messageBodyPart); 

      // Put parts in message 
      msg.setContent(_multipart); 

      // send email 
      Transport.send(msg); 

      return true; 
    } else { 
      return false; 
    } 
  } 

  public void addAttachment(String filename) throws Exception { 
    BodyPart messageBodyPart = new MimeBodyPart(); 
    DataSource source = new FileDataSource(filename); 
    messageBodyPart.setDataHandler(new DataHandler(source)); 
    messageBodyPart.setFileName(filename); 

    _multipart.addBodyPart(messageBodyPart); 
  } 

  @Override 
  public PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(_user, _pass); 
  } 

  private Properties _setProperties() { 
    Properties props = new Properties(); 

    props.put("mail.smtp.host", _host); 

    if(_debuggable) { 
      props.put("mail.debug", "true"); 
    } 

    if(_auth) { 
      props.put("mail.smtp.auth", "true"); 
    } 

    props.put("mail.smtp.port", _port); 
    props.put("mail.smtp.socketFactory.port", _sport); 
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
    props.put("mail.smtp.socketFactory.fallback", "false"); 

    return props; 
  } 

  // the getters and setters 
  public String getBody() { 
    return _body; 
  } 

  public void setBody(String _body) { 
    this._body = _body; 
  } 

  // more of the getters and setters ….. 
} 

现在我要经历每一段代码

public Mail() { 
  _host = "smtp.gmail.com"; // default smtp server 
  _port = "465"; // default smtp port 
  _sport = "465"; // default socketfactory port 

  _user = ""; // username 
  _pass = ""; // password 
  _from = ""; // email sent from 
  _subject = ""; // email subject 
  _body = ""; // email body 

  _debuggable = false; // debug mode on or off - default off 
  _auth = true; // smtp authentication - default on 

  _multipart = new MimeMultipart(); 

  // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
  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); 
} 

public Mail(String user, String pass) { 
  this(); 

  _user = user; 
  _pass = pass; 
} 

在这段代码中,我们初始化属性,并设置默认值。

另外,我们正在设置javamail的mime类型。我还添加了一条评论,说明我们为什么需要这个。

你可能已经注意到有2个构造函数 - 一个覆盖另一个,只是想要在实例化类时传递用户名和密码。

public boolean send() throws Exception { 
  Properties props = _setProperties(); 

  if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
    Session session = Session.getInstance(props, this); 

    MimeMessage msg = new MimeMessage(session); 

    msg.setFrom(new InternetAddress(_from)); 

    InternetAddress[] addressTo = new InternetAddress[_to.length]; 
    for (int i = 0; i < _to.length; i++) { 
      addressTo[i] = new InternetAddress(_to[i]); 
    } 
    msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

    msg.setSubject(_subject); 
    msg.setSentDate(new Date()); 

    // setup message body 
    BodyPart messageBodyPart = new MimeBodyPart(); 
    messageBodyPart.setText(_body); 
    _multipart.addBodyPart(messageBodyPart); 

    // Put parts in message 
    msg.setContent(_multipart); 

    // send email 
    Transport.send(msg); 

    return true; 
  } else { 
    return false; 
  } 
} 

这是最重要的方法 - 在这里我们将来自属性的所有数据并发送邮件。

public void addAttachment(String filename) throws Exception { 
  BodyPart messageBodyPart = new MimeBodyPart(); 
  DataSource source = new FileDataSource(filename); 
  messageBodyPart.setDataHandler(new DataHandler(source)); 
  messageBodyPart.setFileName(filename); 

  _multipart.addBodyPart(messageBodyPart); 
} 

如果要添加附件,可以随时调用此方法,但请确保在发送方法之前调用它。

private Properties _setProperties() { 
  Properties props = new Properties(); 

  props.put("mail.smtp.host", _host); 

  if(_debuggable) { 
    props.put("mail.debug", "true"); 
  } 

  if(_auth) { 
    props.put("mail.smtp.auth", "true"); 
  } 

  props.put("mail.smtp.port", _port); 
  props.put("mail.smtp.socketFactory.port", _sport); 
  props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
  props.put("mail.smtp.socketFactory.fallback", "false"); 

  return props; 
} 

这里我们设置了邮件检索的属性 - 默认为SMTP身份验证。

另请注意,这些都是默认连接到Gmail(Google)SMTP服务器。

以下是如何在Android活动中使用Mail包装器的示例。

@Override 
public void onCreate(Bundle icicle) { 
  super.onCreate(icicle); 
  setContentView(R.layout.main); 

  Button addImage = (Button) findViewById(R.id.send_email); 
  addImage.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
      Mail m = new Mail("gmailusername@gmail.com", "password"); 

      String[] toArr = {"bla@bla.com", "lala@lala.com"}; 
      m.setTo(toArr); 
      m.setFrom("wooo@wooo.com"); 
      m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device."); 
      m.setBody("Email body."); 

      try { 
        m.addAttachment("/sdcard/filelocation"); 

        if(m.send()) { 
          Toast.makeText(MailApp.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); 
        } else { 
          Toast.makeText(MailApp.this, "Email was not sent.", Toast.LENGTH_LONG).show(); 
        } 
      } catch(Exception e) { 
        //Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show(); 
        Log.e("MailApp", "Could not send email", e); 
      } 
    } 
  }); 
} 

答案 1 :(得分:0)

这是您必须在将触发邮件的功能中编写的Android代码段。

将在Async中运行的类

class RetrieveFeedTask extends AsyncTask<String, Void,String> {

private Exception exception;

protected String doInBackground(String... urls) {
    try {
        // Creating HTTP client
        HttpClient httpClient = new DefaultHttpClient();
        // Creating HTTP Post
        HttpPost httpPost = new HttpPost(
                "<url>/api.php");

        // Building post parameters
        // key and value pair
        List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(5);
        nameValuePair.add(new BasicNameValuePair("x", "1"));
        nameValuePair.add(new BasicNameValuePair("lat", "<email id>"));
        nameValuePair.add(new BasicNameValuePair("long", "Hi"));
        nameValuePair.add(new BasicNameValuePair("message", "hi"));
        nameValuePair.add(new BasicNameValuePair("header", "Hi"));

        // Url Encoding the POST parameters
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
        } catch (UnsupportedEncodingException e) {
            // writing error to Log
            e.printStackTrace();
        }

        // Making HTTP Request
        try {
            HttpResponse response = httpClient.execute(httpPost);

            // writing response to log
            Log.d("Http Response:", response.toString());
            return response.toString();
        } catch (ClientProtocolException e) {
            // writing exception to log
            e.printStackTrace();
        } catch (IOException e) {
            // writing exception to log
            e.printStackTrace();

        }

    } catch (Exception e) {
        this.exception = e;
        return null;
    }
    return null;

}

protected void onPostExecute(String feed) {
    // TODO: check this.exception 
    // TODO: do something with the feed
}
}

现在你可以这样打电话

new RetrieveFeedTask().execute(
            "<url>/api.php");

在api.php中,你可以提取你通过POST请求发送的所有参数,然后发送普通的php邮件。

<?php
extract($_POST);
mail($to,$subject,$message,$header);
echo "Sent";

?>

应该这样做。