2017-09-06 3 views
-1

Je peux envoyer un e-mail en arrière-plan, mais je ne comprends pas pourquoi l'utilisation de la méthode addAttachment() de la classe "Mail.java" ne fonctionne pas. J'ai cherché partout des réponses, mais je n'ai trouvé que des réponses «similaires» qui n'ont pas aidé. Tout ce que je veux, c'est envoyer une image de mon dossier res/drawable.L'envoi d'e-mails (en arrière-plan) fonctionne, l'ajout de pièce jointe ne fonctionne pas

Je suis actuellement en train d'emprunter le code de steveholt55's Github dans une tentative d'obtenir la pièce jointe à envoyer .. mais toujours pas de chance. Jusqu'à présent, l'email envoie sans la ligne addAttachment() dans mon activité, ce qui est une bonne nouvelle. Mais j'ai besoin de cet attachement pour envoyer aussi. Le fichier Mail.Java est ci-dessous, mais je pense que le problème est quelque part dans mon code .. spécifiquement où j'essaye d'ajouter la pièce jointe dans mon activité. La méthode addAttachment() demande uniquement une valeur de chaîne. Je me demande si je lui donne le mauvais chemin?

code de mon activité:

if(!sent){ 
    try{ 

     String[] recipients = {"[email protected]"}; 
     SendEmailAsyncTask email = new SendEmailAsyncTask(); 
     email.m = new Mail(Config.EMAIL,Config.PASSWORD); 
     email.m.set_from("[email protected]"); 
     email.m.setBody("Body Text"); 
     email.m.set_subject("Subject Text"); 
     email.m.set_to(recipients); 
     email.m.addAttachment("res/drawable-hdpi/add_down.png"); 
     email.execute(); 

    } catch(Exception e){e.printStackTrace();} 
} 

Voici la classe Async:

class SendEmailAsyncTask extends AsyncTask<Void, Void, Boolean> { 
    Mail m; 

    public SendEmailAsyncTask() { } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     boolean returnvalue = false; 

     try { 
      if (m.send()) 
       returnvalue = true; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return returnvalue; 
    } 
} 

Ci-dessous la Mail.Java Classe:

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); 

      msg.setHeader("X-Priority", "1"); 
      // 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 String get_user() { 
     return _user; 
    } 

    public void set_user(String _user) { 
     this._user = _user; 
    } 

    public String get_pass() { 
     return _pass; 
    } 

    public void set_pass(String _pass) { 
     this._pass = _pass; 
    } 

    public String[] get_to() { 
     return _to; 
    } 

    public void set_to(String[] _to) { 
     this._to = _to; 
    } 

    public String get_from() { 
     return _from; 
    } 

    public void set_from(String _from) { 
     this._from = _from; 
    } 

    public String get_port() { 
     return _port; 
    } 

    public void set_port(String _port) { 
     this._port = _port; 
    } 

    public String get_sport() { 
     return _sport; 
    } 

    public void set_sport(String _sport) { 
     this._sport = _sport; 
    } 

    public String get_host() { 
     return _host; 
    } 

    public void set_host(String _host) { 
     this._host = _host; 
    } 

    public String get_subject() { 
     return _subject; 
    } 

    public void set_subject(String _subject) { 
     this._subject = _subject; 
    } 

    public boolean is_auth() { 
     return _auth; 
    } 

    public void set_auth(boolean _auth) { 
     this._auth = _auth; 
    } 

    public boolean is_debuggable() { 
     return _debuggable; 
    } 

    public void set_debuggable(boolean _debuggable) { 
     this._debuggable = _debuggable; 
    } 

    public Multipart get_multipart() { 
     return _multipart; 
    } 

    public void set_multipart(Multipart _multipart) { 
     this._multipart = _multipart; 
    } 
} 
+0

obviosuly vous ne pouvez pas obtenir le fichier drawable comme ça ... 1. grab Drawable, 2. enregistrer sur un certain chemin, utilisez ce chemin ... comment faire les deux 1 et 2 ont été répondu à bazillions questions similaires ici – Selvin

+0

Merci - S'il vous plaît essayez d'être un peu moins grossier cependant. Je ne suis pas un expert, j'apprends. J'ai été debout pendant plus de 30 heures en essayant de travailler tout cela. Ce projet a été lancé au hasard par mon patron, qui s'attend à ce que cela se fasse dans un autre jour. – FoxDonut

+0

vous pouvez obtenir le chemin de l'drawable comme ce chemin Uri = Uri.parse ("android.resource: //" + BuildConfig.APPLICATION_ID + "/" + R.drawable.image) et vous pouvez utiliser comme ce nom de fichier – Kayra

Répondre

0

Comme demandé dans votre commentaire, mon commentaire comme réponse (avec un peu plus de code pour clarifier les choses). Selvin vous a indiqué la bonne direction, que vous ne pouvez pas envoyer de bitmap en pièce jointe car c'est juste une structure de données interne, mais vous devez la convertir en quelque chose que le destinataire peut utiliser, par exemple. un PNG dans votre cas.

Au lieu d'écrire dans le système de fichiers, vous pouvez le générer en mémoire. De cette façon, vous n'avez pas besoin de l'autorisation d'écrire dans le stockage des périphériques (si vous n'en avez pas déjà besoin pour d'autres choses) et vous n'avez pas besoin de le nettoyer après avoir envoyé le courrier avec succès. Java EE est fourni avec une ByteArrayDataSource. Si vous avez cette classe disponible dans votre application, remplacez simplement FileDataSource par ByteArrayDataSource et renvoyez l'image compressée sous forme de byte array. Parce que je ne sais pas si vous avez cette classe disponible dans votre projet, ce qui suit est une solution qui n'utilise pas DataHandlers.

Voici quelques exemple de code montrant mon point:

public byte[] getImageData(Bitmap bitmapImage) { 
    ByteArrayOutputStream bos = null; 
    try { 
     bos = new ByteArrayOutputStream(); 
     // Use the compress method on the BitMap object to write image to the OutputStream 
     bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, bos); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return baos.toByteArray(); 
} 

Au lieu d'un DataSource un tableau d'octets est retourné. Les données sont ensuite ajouté en pièce jointe comme ceci:

public void addAttachment(byte[] data, String filename) throws Exception { 
    BodyPart messageBodyPart = new MimeBodyPart(); 
    messageBodyPart.setFileName(MimeUtility.encodeText(filename, "UTF-8", null)); 
    messageBodyPart.setContent(data, "image/png"); 
    _multipart.addBodyPart(messageBodyPart); 
} 
0

La question était que j'étais essayer d'ajouter un chemin de fichier qui était incorrect ... complètement. Crédit à @Selvin qui m'a indiqué dans la bonne direction.

Je dois stocker l'image que je voulais envoyer dans le stockage interne de mon appareil, puis donner le chemin de ce fichier interne. Voici la fonction que j'ai utilisée pour stocker le fichier dans le stockage interne, qui renvoie également un nom de chemin d'accès String.

public String saveToInternalStorage(Bitmap bitmapImage) { 
    ContextWrapper wrapper = new ContextWrapper(getApplicationContext()); 
    File directory = wrapper.getDir("images", Context.MODE_PRIVATE); 
    File path = new File(directory, "output.png"); 

    FileOutputStream fos = null; 
    try { 
     fos = new FileOutputStream(path); 
     // Use the compress method on the BitMap object to write image to the OutputStream 
     bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      fos.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    return path.getAbsolutePath(); 
} 

Dans ma fonction, j'ai utilisé le code ci-dessous pour passer ma res/drawable/img dans la méthode ci-dessus:

String path = saveToInternalStorage(BitmapFactory.decodeResource(getResources(), R.drawable.add_up)); 

Il convient également de noter que j'ai 4 dossiers étirables (drawable- ldpi, drawable-mdpi, drawable-hdpi et drawable-xhdpi). Le dossier dessinable sélectionné est relatif à votre appareil en sélectionnant la "meilleure image" pour lui-même. Pour être plus clair, les appareils avec une résolution plus élevée prendront des images des dossiers hdpi et xhdpi ... et je pense que vous avez l'idée.

+0

Au lieu d'une FileDataSources, il en existe d'autres qui autorisent les opérations en mémoire, donc l'enregistrement dans le système de fichiers n'est pas strictement nécessaire. – Lothar

+0

@Lothar Veuillez fournir ceci comme réponse. Personne d'autre n'a été en mesure de fournir cette information ou de fournir une meilleure solution que ce que j'ai. – FoxDonut