nedimf / maildroid

Maildroid is a small robust android library for sending emails using SMTP server
188 stars 24 forks source link

Callbacks not being called when uploading large file #24

Closed ZumWoelkchen closed 4 years ago

ZumWoelkchen commented 4 years ago

I'm using this library to send images taken by the camera. It works as expected but i have a major issue. The Callbacks aren't reliable. It doesnt call onSuccess or onFail even though the message got through as expected.

    MaildroidX.Builder()
        .smtp("***")
        .smtpUsername("***")
        .smtpPassword("***")
        .port("***")
        .type(MaildroidXType.HTML)
        .to("***")
        .from("***")
        .subject(subject)
        .body(body)
        .attachment(getRealPathFromUri(this, image_uri)!!)
        .isJavascriptDisabled(true)
        .onCompleteCallback(object : MaildroidX.onCompleteCallback{
            override val timeout: Long = 3000
            override fun onSuccess() {
                println("Email Sent!")
            }
            override fun onFail(errorMessage: String) {
                print("Email Failed!")
            }
        })
        .mail()

Logcat output is: W/Success: Success, mail sent [STATUS: true] onSuccess nor onFail fired.

It appears to work fine when i remove the image attachment. Attachment size is approx 3MB. Increasing the Timeout to 30 seconds doesnt fix the issue.

nedimf commented 4 years ago

Can you try setting it to false. It's the new feature, so that is maybe causing the issue. .isJavascriptDisabled(false) This means 3000 3 seconds. 30000 is 30 seconds for timeout.

nedimf commented 4 years ago

@ZumWoelkchen is problem still present?

ZumWoelkchen commented 4 years ago

@nedimf Problem is still present with .isJavascriptDisabled(false)

I will try to track it down further. Pretty sure the problem only occurs with "larger" files. Will report back!

ZumWoelkchen commented 4 years ago

@nedimf As suspected the problem only occurs on large files. I compressed the images to ~300kB and it works perfectly now!

How does the timeout work? Will it only timeout when the app can't establish a connection to the email server (e.g. bad cellular reception, no wifi, ...) or does it always timeout when exceeding the time set even while the mail is still sending?

I'd love to say the problem is solved but the problem still persists on larger files. It's fine for my usecase but maybe someone else will stumble into the same problem at some point. Still i am very satisfied with your work!

nedimf commented 4 years ago

@ZumWoelkchen Timeout in the app works in a way that it always times out by time factor you specify. That is because app is wrapping around JavaMail API/Jakarta Mail which is ancient project by now and does not give us any timeout information we can use. So if mail is not sent in that amount of milliseconds specified, app will throw the error.

Library compressing the file is not really ideal, I would rather let user to deal with that. If you have any code snippet that you used to compress file be free to comment on this post so if anyone else has such problem can have idea what has to be done.

Thanks for the kind words. Nedim

ZumWoelkchen commented 4 years ago

That's a pity but i'll just set it to 30.000ms to give some headroom.

While compressing the images is not ideal it's not a problem in my usecase. The app is only targeted to people in our company (delivery) and drivers can send photos from dropoff places, damages and so on. Quality doesnt really matter.

Im using the compressor library from zelory. Just add this to gradle implementation 'id.zelory:compressor:3.0.0'

Compression can't be called from the UI Thread. I'm using an experimental library to do inline async calls. Which is not recommended and experimental coroutine support will be dropped soon!

Async library by metalab: implementation 'co.metalab.asyncawait:asyncawait:1.0.0'

Additional Librarys: implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1"

Compression function: suspend fun compressImage(){ val compressedImageFile = Compressor.compress(context, File("path/to/image.lpg")) { default() destination(File("path/to/image.lpg")) } }

Can be called like this: async{ compressImage() }

nedimf commented 4 years ago

Sadly I can't do anything about it, I know thats issue but the JavaMail that library are using, can't give us that data. Thank you for sharing @ZumWoelkchen. I'll be closing this issue now.