2015-11-17 28 views
5

Sto cercando di creare una semplice app di posta elettronica utilizzando l'API Java Mail Java (https://code.google.com/p/javamail-android/) che invierà la posta con un allegato. Ma il mio approccio non funziona. Invia con successo il testo dell'email ma non aggiunge l'allegato con l'e-mail. Ho aggiunto un pulsante immagine per selezionare un file per l'allegato. Sto usando Intento per selezionare un file. Inoltre ha aggiunto un altro pulsante per inviare e-mail.Applicazione Android per inviare e-mail con allegato utilizzando l'API Java Mail

Inizialmente, facendo clic sul pulsante Immagine, sto provando a selezionare il file e ottenere il percorso del file per l'allegato. Quindi sto impostando il percorso del file sul metodo sendmail per l'invio della posta con questo allegato.

quello che sto facendo è il seguente:

Email.java

package com.android.imran.emailapp003; 

import java.util.Date; 
import java.util.List; 
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 Email extends javax.mail.Authenticator { 
    private String _user; 
    private String _pass; 

    private List<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 Email() { 
     _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 Email(String user, String pass) { 
     this(); 

     _user = user; 
     _pass = pass; 
    } 

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

     if(!_user.equals("") && !_pass.equals("") && _to.size() > 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.size()]; 
      for (int i = 0; i < _to.size(); i++) { 
       addressTo[i] = new InternetAddress(_to.get(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; 
    } 

    public List<String> getTo(){ 
     return _to; 
    } 
    public void setTo(List<String> toArr) { 
     this._to = toArr; 
    } 

    public String getFrom(){ 
     return _from; 
    } 
    public void setFrom(String from){ 
     this._from = from; 
    } 

    public String getSubject(){ 
     return _subject; 
    } 
    public void setSubject(String string) { 
     this._subject = string; 
    } 
} 

ProcessEmail.java

package com.android.imran.emailapp003; 

import android.app.Activity; 
import android.app.ProgressDialog; 
import android.os.AsyncTask; 
import android.util.Log; 

import java.util.List; 

public class ProcessEmail extends AsyncTask { 

    private ProgressDialog statusDialog; 
    private Activity sendMailActivity; 

    public ProcessEmail(Activity activity) { 
     sendMailActivity = activity; 
    } 

    protected void onPreExecute() { 
     statusDialog = new ProgressDialog(sendMailActivity); 
     statusDialog.setMessage("Getting ready..."); 
     statusDialog.setIndeterminate(false); 
     statusDialog.setCancelable(false); 
     statusDialog.show(); 
    } 

    @Override 
    protected Object doInBackground(Object... args) { 
     try { 
      Log.i("SendMailTask", "About to instantiate GMail..."); 
      publishProgress("Processing input...."); 
      Email sendMail = new Email(args[0].toString(), args[1].toString()); 

      publishProgress("Preparing mail message...."); 
      sendMail.setFrom(args[0].toString()); 
      sendMail.setTo((List<String>) args[2]); 
      sendMail.setSubject(args[3].toString()); 
      sendMail.setBody(args[4].toString()); 
      sendMail.addAttachment(args[5].toString()); 

      publishProgress("Sending email...."); 
      sendMail.send(); 

      publishProgress("Email Sent."); 
      Log.i("SendMailTask", "Mail Sent."); 
     } catch (Exception e) { 
      publishProgress(e.getMessage()); 
      Log.e("SendMailTask", e.getMessage(), e); 
     } 
     return null; 
    } 

    @Override 
    public void onProgressUpdate(Object... values) { 
     statusDialog.setMessage(values[0].toString()); 

    } 

    @Override 
    public void onPostExecute(Object result) { 
     statusDialog.dismiss(); 
    } 

} 

MainActivity.java

package com.android.imran.emailapp003; 

import android.content.Intent; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageButton; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class MainActivity extends AppCompatActivity { 

    private static int FILE_SELECT_CODE; 
    private static int SELECT_PICTURE; 
    String FilePath; 

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

     Button addImage = (Button) findViewById(R.id.send_email); 
     addImage.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       String fromEmail = "*******@gmail.com"; 
       String fromPassword = "*****"; 
       List<String> toEmails = new ArrayList(); 
       toEmails.add("*******@gmail.com"); 
       toEmails.add("*******@live.com"); 
       String emailSubject = "This is an email sent using my Mail JavaMail wrapper from an Android device."; 
       String emailBody= "Email body."; 
       new ProcessEmail(MainActivity.this).execute(
         fromEmail, fromPassword, toEmails, emailSubject, emailBody, FilePath); 
      } 
     }); 

     ImageButton selectFile= (ImageButton) findViewById(R.id.selectFile); 
     selectFile.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
       intent.setType("*/*"); 
       startActivityForResult(intent, FILE_SELECT_CODE); 
      } 
     }); 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if ((requestCode == FILE_SELECT_CODE) && (resultCode == -1)) { 
      FilePath = data.getData().getPath(); 
      //Toast.makeText(this, FilePath, Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

Please help me per risolvere il problema.

Aggiornamento: Nel mio emulatore Genymotion ho selezionato un file. La mia app mostra il percorso del file come /external/images/images/14 nel messaggio di toast.

Quindi quando faccio clic sul pulsante di invio per inviare l'e-mail. Ho ricevuto il seguente errore:

11-17 04:47:46.887 25788-26024/com.android.imran.emailapp003 E/SendMailTask﹕ IOException while sending message 
    javax.mail.MessagingException: IOException while sending message; 
    nested exception is: 
    java.io.FileNotFoundException: /external/images/media/14: open failed: ENOENT (No such file or directory) 
      at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:676) 
      at javax.mail.Transport.send0(Transport.java:189) 
      at javax.mail.Transport.send(Transport.java:118) 
      at com.android.imran.emailapp003.Email.send(Email.java:105) 
      at com.android.imran.emailapp003.ProcessEmail.doInBackground(ProcessEmail.java:42) 
      at android.os.AsyncTask$2.call(AsyncTask.java:287) 
      at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
      at java.lang.Thread.run(Thread.java:841) 
    Caused by: java.io.FileNotFoundException: /external/images/media/14: open failed: ENOENT (No such file or directory) 
      at libcore.io.IoBridge.open(IoBridge.java:409) 
      at java.io.FileInputStream.<init>(FileInputStream.java:78) 
      at javax.activation.FileDataSource.getInputStream(FileDataSource.java:110) 
      at javax.activation.DataHandler.writeTo(DataHandler.java:318) 
      at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403) 
      at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:874) 
      at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:444) 
      at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:102) 
      at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:897) 
      at javax.activation.DataHandler.writeTo(DataHandler.java:330) 
      at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403) 
      at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1745) 
      at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:636) 
            at javax.mail.Transport.send0(Transport.java:189) 
            at javax.mail.Transport.send(Transport.java:118) 
            at com.android.imran.emailapp003.Email.send(Email.java:105) 
            at com.android.imran.emailapp003.ProcessEmail.doInBackground(ProcessEmail.java:42) 
            at android.os.AsyncTask$2.call(AsyncTask.java:287) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
            at java.lang.Thread.run(Thread.java:841) 
    Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory) 
      at libcore.io.Posix.open(Native Method) 
      at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 
      at libcore.io.IoBridge.open(IoBridge.java:393) 
            at java.io.FileInputStream.<init>(FileInputStream.java:78) 
            at javax.activation.FileDataSource.getInputStream(FileDataSource.java:110) 
            at javax.activation.DataHandler.writeTo(DataHandler.java:318) 
            at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403) 
            at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:874) 
            at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:444) 
            at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:102) 
            at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:897) 
            at javax.activation.DataHandler.writeTo(DataHandler.java:330) 
            at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1403) 
            at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1745) 
            at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:636) 
            at javax.mail.Transport.send0(Transport.java:189) 
            at javax.mail.Transport.send(Transport.java:118) 
            at com.android.imran.emailapp003.Email.send(Email.java:105) 
            at com.android.imran.emailapp003.ProcessEmail.doInBackground(ProcessEmail.java:42) 
            at android.os.AsyncTask$2.call(AsyncTask.java:287) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
            at java.lang.Thread.run(Thread.java:841) 
11-17 04:48:58.359 25788-25788/com.android.imran.emailapp003 W/EGL_genymotion﹕ eglSurfaceAttrib not implemented 

Ho eseguito l'applicazione nel mio dispositivo Android. Ho selezionato un file e la mia app ha mostrato il percorso del file come /documento/immagini: 52721 nel messaggio di toast. Ma il percorso effettivo del file è "/ Internal Storage/DCIM/Camera/01.jpg"

Penso che la mia applicazione non ottenga il percorso effettivo per il file allegato. Come si può ottenere il percorso effettivo per il file allegato?

risposta

0

Hai scritto questo: :

 sendMail.setTo((List<String>) args[2]); 
     sendMail.setSubject(args[3].toString()); 
     sendMail.setBody(args[4].toString()); 
     //sendMail.addAttachment(args[5].toString()); <- Error here 
     publishProgress("Sending email...."); 
     sendMail.send(); 

      : 

Si prega di rimuovere il commento le righe precedenti marcate.

+0

anche u può provare questo: [link] (http://www.tutorialspoint.com/javamail_api/javamail_api_send_email_with_attachment.htm) –

+0

Grazie per il tuo commento. In realtà nel mio Studio Android ho eseguito il codice senza commentare la riga sendMail.addAttachment (args [5] .toString()); Ma ancora non funziona. –

+0

Penso che non possa riconoscere la posizione del mio file. :( –

1

Prova questo per ottenere il vostro percorso del file:

Uri selectedData = data.getData(); 
    String[] filePathcolumn = {MediaStore.Files.FileColumns.DATA}; 

    Cursor cursor = getContentResolver().query(selectedData, filePathcolumn, null, null, null); 
    cursor.moveToFirst(); 
    Log.d(TAG, DatabaseUtils.dumpCursorToString(cursor)); 
    columnindex = cursor.getColumnIndex(filePath[0]); 
    attachFile = selectedData.toString(); 
    filePath = Uri.parse(attachFile);  
    cursor.close();