Search code examples
androidapigmaillistenerprogress

Check progress for Upload (Google GMail API for Android)


I'm getting frustrated trying to get information about the progress of my asynctask while inserting a mail through Gmail Api for Android.

I'm trying to use the MediaHttpUploaderProgressListener but the problem is that i just get null out of the getMediaHttpUploader() method of the insert.

I think i'm missing something big in the middle to get the expected response out of the getMediaHttpUploader...

This is my code:

private class TareaGestionEnvioMails extends AsyncTask<Void, Void, Message> {
    @Override
    protected Message doInBackground(Void... params) {
        try {
            if (mensaje != null) {
                String user = "me";

                Gmail.Users.Messages.Insert insert = servicioGmail.users().messages().insert(user, mensaje);
                MediaHttpUploader uploader = insert.getMediaHttpUploader();
                //getMediaHttpUploader returns me null value :(
                uploader.setDirectUploadEnabled(false);
                uploader.setChunkSize(1024*256);
                uploader.setProgressListener(new FileUploadProgressListener());

                mensaje = insert.execute();
            }
            return mensaje;
        } catch (Exception e) {
            mLastError = e;
            cancel(true);
            return null;
        }
    }
...

    private class FileUploadProgressListener implements MediaHttpUploaderProgressListener {

    public FileUploadProgressListener() {
    }

    @Override
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException {
        if (mediaHttpUploader == null) return;
        switch (mediaHttpUploader.getUploadState()) {
            case INITIATION_STARTED:
                pantallaPrincipal.onProgresoEnviarMail(0.0, "INITIATION_STARTED");
                break;
            case INITIATION_COMPLETE:
                pantallaPrincipal.onProgresoEnviarMail(0.0, "INITIATION_COMPLETE");
                break;
            case MEDIA_IN_PROGRESS:
                double percent = mediaHttpUploader.getProgress() * 100;
                pantallaPrincipal.onProgresoEnviarMail(percent, "MEDIA_IN_PROGRESS");
                break;
            case MEDIA_COMPLETE:
                pantallaPrincipal.onProgresoEnviarMail(100.0, "MEDIA_COMPLETE");
        }
    }
}

Thanks Everyone! This is my first time posting on Stackoverflow!


Solution

  • Solved!!!!

    You have to use the three parameter version of the insert() method. I've filled the third parameter with my MimeMessage this way:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    myMimeMessage.writeTo(baos);
    AbstractInputStreamContent mediaContent = new ByteArrayContent("message/rfc822", baos.toByteArray());
    Gmail.Users.Messages.Insert insert = servicioGmail.users().messages().insert(user, null, mediaContent);
    

    There are two things you have to be aware of:

    1) If you keep using the "Message" and the "AbstractInputStreamContent" parameters both at the same time, you will be happy with little messages... But if you have to upload a message bigger than around 1mb, you will get a horrible 400 Bad_Request exception with a "Request too large" error. So, leave the Message parameter null.

    2) Leaving the "Message" parameter null, you can't set the Label of the message... so you will have to fill it later using users().messages().modify method.

    If anyone have a nicer workaround to insert a big mail and it's label at the same time, and having a feedback of the progress, please comment! Thanks!