Mail versenden in Kotlin

  • Antworten:37
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 308

30.04.2020, 21:16:31 via Website

Hallo zusammen

Ich möchte mit Kotlin ein Mail versenden. Ich finde aber nur Beispiele für Java.

Kann man in Kotlin keine Mail versenden. Falls es doch geht, hat jemand ein Beispiel dafür.

Ich habe es mal auf diesem Weg versucht. Aber der führt nur zu einem Absturz.

private fun sendMail(){
    var to : String
    var cc : String
    val mailsender = Intent(ctx, Intent.ACTION_SEND::class.java)

    to = "renato_robbiani@bluewin.ch"
    cc = "renato.robbiani@robbisoft.ch"

    mailsender.setData(Uri.parse("mailto:"))
    mailsender.setType("text/plain")
    mailsender.putExtra(Intent.EXTRA_EMAIL, to)
    mailsender.putExtra(Intent.EXTRA_CC, cc)
    mailsender.putExtra(Intent.EXTRA_SUBJECT, "Test")
    mailsender.putExtra(Intent.EXTRA_TEXT, "Das ist eine E-Mail")

    startActivity(Intent.createChooser(mailsender, "Send mail..."));
}

Gruss Renato

Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 1.218

02.05.2020, 12:34:33 via Website

Solltest du wirklich nichts Passendes finden. Hier eine Klasse die eine Mail mit Datei Anhang sendet. Mit der Java API.
Hatte ich in Java und habe sie in Kotlin übersetz.

class SendMail(private val attachFilePath: String) : AsyncTask<Void?, Void?, Void?>() {

private val EMAIL = "..." // SMTP Mail Account
private val PASSWORD = "..." // SMTP PW
private val SMTPHOST = "..." // SMTP Adresse
private var session: Session? = null

//Information to send email
private val email = "...@..." // Empfänger Adresse
private val subject = "Hallo"
private val message = "Neue Daten"

protected override fun doInBackground(vararg params: Void?): Void? {
    //Creating properties
    val props = Properties()
    props.setProperty("mail.transport.protocol", "smtp")
    props["mail.smtp.host"] = SMTPHOST
    props["mail.smtp.socketFactory.port"] = "465"
    props["mail.smtp.port"] = "465"
    props["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
    props["mail.smtp.auth"] = "true"
    props["mail.smtp.socketFactory.fallback"] = "false"
    props.setProperty("mail.smtp.quitwait", "false")

    //Creating a new session
    session = Session.getDefaultInstance(props, object : Authenticator() {
        //Authenticating the password
        override fun getPasswordAuthentication(): PasswordAuthentication {
            return PasswordAuthentication(EMAIL, PASSWORD)
        }
    })
    try {
        //Creating MimeMessage object
        val mm = MimeMessage(session)
        //Setting sender address
        mm.setFrom(InternetAddress(EMAIL))
        mm.addRecipient(Message.RecipientType.TO, InternetAddress(email))
        mm.subject = subject
        val mp: Multipart = MimeMultipart()
        val htmlPart = MimeBodyPart()
        htmlPart.setContent(message, "text/plain")
        mp.addBodyPart(htmlPart)
        val attachment = MimeBodyPart()
        val source: DataSource = FileDataSource(attachFilePath)
        attachment.dataHandler = DataHandler(source)
        attachment.fileName = File(attachFilePath).name
        mp.addBodyPart(attachment)
        mm.setContent(mp)
        //Sending email
        Transport.send(mm)
    } catch (e: MessagingException) {
        e.printStackTrace()
    }
    return null
}

}

aufruf der Klasse

    var sm2 =  SendMail("path zum Mail Anhang")
    sm2.execute()

natürlich brauchst du auch die libs und musst sie auch unter dependencies einbinden.

so nun viel Erfolg.

— geändert am 02.05.2020, 12:39:07

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 11.012

30.04.2020, 21:29:13 via Website

Was ist denn die Fehlermeldung?

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

30.04.2020, 22:23:08 via Website

Hallo auch wenn du kein beispiel dazu finden solltest ist es doch auch möglich java Code nach kotlin übersetzen zu lassen.
Klar der do erstellte code ist dann meist nicht so schön kompakt aber lauffähig.

Aber eigentlich kannst du ja java und hast dir die Grundlagen von kotlin beigebracht.
Anhand einen Java Beispiel sollte es ohne große Aufwand möglich sein ein Java Email intent nach kotlin zu übersetzen.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

01.05.2020, 12:28:51 via Website

Hallo
eigentlich willst du einen Impliziten Intent und nicht einen Expiziten Intent.

val mailsender = Intent(Intent.ACTION_SEND)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 308

01.05.2020, 21:19:38 via Website

Ciao Jokel

So geht es. Aber es wird nur die Mail App geöffnet. Aber ich möchte, dass das Mail direkt versandt wird. Ich denke, dass es auf diesem Weg nicht geht.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

01.05.2020, 22:37:02 via Website

Genau mit einem intent habe ich es noch nicht geschaft das eine Mail ohne eine Bestätigung des Users zu senden.
Gleich ob java oder kotlin.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 11.012

02.05.2020, 10:45:04 via App

Nein ohne Bestätigung geht aus gutem Grund nicht.
Sonst können Apps ja Spam von deinem Mail Account senden ohne dass du es merkst.
Wenn du selber einen Mailserver oder eine Domain mit Mailserver hast kannst du darüber Mails verschicken, aber dann halt nicht mit Namen des Users.
Was willst du damit machen?

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

02.05.2020, 11:29:38 via Website

Hallo

Nein ohne Bestätigung geht aus gutem Grund nicht.

Na ganz so dass es überhaupt nicht geht ist es nicht. Mit einen Intent sicher nicht den da rufst du die Android eigene App auf, und da ist es eben so das auf eine User Eingabe gewartet wird.

Um eine E-Mail im Hinderung ohne User Eingabe verschicken zu könne. Musst selber den SMTP Server deines Providers benutzen. Entweder du machst alles selber oder benutzt die Standard Java Bibliotheken.
Die du aber erst laden und dem Projekt hinzufügen musst.

Hier ein Link dafür.
Ist zwar in Java aber wie ich aus deinen vorherigen Threads weis kannst du das ja. Also sollte es dir möglich sein das nach Kotlin zu übersetzen. Das bietet dir AS auch an, eine Java Kasse nach Kotlin zu übersetzen.

https://www.simplifiedcoding.net/android-email-app-using-javamail-api-in-android-studio/

— geändert am 02.05.2020, 11:33:31

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 308

02.05.2020, 11:36:03 via Website

Ciao Pascal

Ich bin daran eine Wetterstation zu bauen. Ich möchte die Messdaten sammeln und einmal am Tag per Mail an mein PC senden. Ich möchte das Mail nicht jeden Tag anstossen müssen. Vielleicht gibt es einen anderen Weg um die Daten zu übertragen. Mal schauen vielleicht kommt mir noch eine Idee. Trotzdem Danke für die Hilfe.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

02.05.2020, 11:41:54 via Website

Hallo @Robbiani Renato
habe dir doch schon einen Link gesucht wie du „Mails im Background“ ohne Intent senden kannst.
Genau danach solltest du im Netz suchen. Da wirst du auch fündig werden.

— geändert am 02.05.2020, 11:42:19

Hilfreich?
Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 1.218

02.05.2020, 12:34:33 via Website

Solltest du wirklich nichts Passendes finden. Hier eine Klasse die eine Mail mit Datei Anhang sendet. Mit der Java API.
Hatte ich in Java und habe sie in Kotlin übersetz.

class SendMail(private val attachFilePath: String) : AsyncTask<Void?, Void?, Void?>() {

private val EMAIL = "..." // SMTP Mail Account
private val PASSWORD = "..." // SMTP PW
private val SMTPHOST = "..." // SMTP Adresse
private var session: Session? = null

//Information to send email
private val email = "...@..." // Empfänger Adresse
private val subject = "Hallo"
private val message = "Neue Daten"

protected override fun doInBackground(vararg params: Void?): Void? {
    //Creating properties
    val props = Properties()
    props.setProperty("mail.transport.protocol", "smtp")
    props["mail.smtp.host"] = SMTPHOST
    props["mail.smtp.socketFactory.port"] = "465"
    props["mail.smtp.port"] = "465"
    props["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
    props["mail.smtp.auth"] = "true"
    props["mail.smtp.socketFactory.fallback"] = "false"
    props.setProperty("mail.smtp.quitwait", "false")

    //Creating a new session
    session = Session.getDefaultInstance(props, object : Authenticator() {
        //Authenticating the password
        override fun getPasswordAuthentication(): PasswordAuthentication {
            return PasswordAuthentication(EMAIL, PASSWORD)
        }
    })
    try {
        //Creating MimeMessage object
        val mm = MimeMessage(session)
        //Setting sender address
        mm.setFrom(InternetAddress(EMAIL))
        mm.addRecipient(Message.RecipientType.TO, InternetAddress(email))
        mm.subject = subject
        val mp: Multipart = MimeMultipart()
        val htmlPart = MimeBodyPart()
        htmlPart.setContent(message, "text/plain")
        mp.addBodyPart(htmlPart)
        val attachment = MimeBodyPart()
        val source: DataSource = FileDataSource(attachFilePath)
        attachment.dataHandler = DataHandler(source)
        attachment.fileName = File(attachFilePath).name
        mp.addBodyPart(attachment)
        mm.setContent(mp)
        //Sending email
        Transport.send(mm)
    } catch (e: MessagingException) {
        e.printStackTrace()
    }
    return null
}

}

aufruf der Klasse

    var sm2 =  SendMail("path zum Mail Anhang")
    sm2.execute()

natürlich brauchst du auch die libs und musst sie auch unter dependencies einbinden.

so nun viel Erfolg.

— geändert am 02.05.2020, 12:39:07

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 11.012

02.05.2020, 13:08:27 via Website

Ich würde die Daten an einen HTTP Server übermitteln und dort speichern.
Von dort kannst du dann auch einfacher E-Mails versenen.
Oder natürlich wie es dir @Jockel gezeigt hat.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 308

03.05.2020, 11:17:53 via Website

Ciao Jokel

Herzlichen Dank für deine Klasse. Die ist ja echt super.
In einem bin ich noch hängen geblieben. Welche jar Dateien muss ich einbinden. Gefunden habe ich folgende:

mail.jar
additionnal.jar
activation.jar

Wahrscheinlich benötige ich noch weitere. Denn in der Klasse möchte Android-Studio noch weiter Klassen erstellen.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

03.05.2020, 13:31:22 via Website

Hallo alle drei wenndu es nicht so wie bei Pascal machen willst.

implementation files('libs/additionnal.jar')
implementation files('libs/mail.jar')
implementation files('libs/activation.jar')

die drei Dtein in den Lib Ordner /app/libs

Das steht alle in dem Link den ich dir zuerst gegeben habe lesen bildet.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

03.05.2020, 15:23:07 via Website

wenn es über das Repos. sein soll.
dann so

implementation 'javax.mail:javax.mail-api:1.6.2'
implementation 'javax.activation:javax.activation-api:1.2.0'

du brauchst beide sonst kannst du keinen Anhang verschicken.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 308

03.05.2020, 18:49:40 via Website

Ciao Jokel

Irgend was mache ich falsch. Es will einfach nicht funktionieren. Meine build.gradle sieht wie folgt aus:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 28

defaultConfig {
    applicationId "ch.robbisoft.sendmail"
    minSdkVersion 19
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'javax.mail:javax.mail-api:1.6.2'
implementation 'javax.activation:javax.activation-api:1.2.0'
}

Die jar-Dateien habe ich unter app/libs abgelegt. Wenn ich nun kompiliere werden die Verknüpfungen nicht gefunden.

Gruss Renato

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 1.218

03.05.2020, 19:07:25 via Website

Wenn du das mit dem repos machst.
Brauchst du die jar Dateien darfst sie auch nicht in dem lib Ordner haben.

Entweder die jar Dateien und die erste Variante im gradle.
Oder ohne jar Dateien die werden dann über das repos geladen.

Dachte das wäre klar gewesen.

— geändert am 03.05.2020, 19:08:15

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 308

03.05.2020, 19:07:26 via Website

Jetzt hat es funktioniert mit dem "import javax.mail.*"

Jetzt sind nur noch zwei Probleme noch offen. Folgende Zeile will er nicht kennen.

session = PackageInstaller.Session.getDefaultInstance(props, object : Authenticator()

Das getDefaultInstance sticht ihm in die Nase und

mm.addRecipient(Message.RecipientType.TO, InternetAddress(email))

der RecipienType will er auch nicht kennen. Mal schauen vielleicht finde ich eine Lösung. Oder weiss jemand woran das liegt.

Gruss Renato

Hilfreich?
Diskutiere mit!
Empfohlene Artikel bei NextPit