Send an Email with attachment
-
-
@onek24
Yes this is a solution, but the user will have to configure the server while I wish that he can use his native client (with address book, ...).In fact I would like to do like the "Send by mail" options of Word, LibreOffice or Calligra. So I looked at the source code of Calligra and it seems to use the
ShellExecuteW
command (in KToolInvocation::invokMailer), but I can not get it to work.Do you have a track?
-
Actually you might have found the solution yourself, just build KService library and link to it to be able to use invokMailer.
Unfortunately that module does not work on android so you'll probably have to implement an android-only solution in an#ifdef
-
Hi,
By helping me with this topic, I try to send an email with native client of my Android Device.
Here is my codes
//JavaClass.java in /android/src/com/company/myapp package com.comany.myapp; import android.content.Intent; import android.app.Activity; import android.util.Log; import android.net.Uri; import org.qtproject.qt5.android.bindings.QtActivity; public class JavaClass extends QtActivity { private static JavaClass m_instance; public JavaClass() { Log.d("Mailer::Mailer", "Constructor"); m_instance = this; } public static void sendMail(String attachmentFilename) { Log.d("Mailer::sendMail", "java-code: sendMail(): 1 file=" + attachmentFilename); Log.d("Mailer::sendMail", "java-code: m_instance=" + m_instance); String f = "file://" + attachmentFilename; Uri uri = Uri.parse(f); try{ Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("message/rfc822"); intent.putExtra(Intent.EXTRA_SUBJECT, "CSV export"); //intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"abc@gmail.com"}); //intent.putExtra(Intent.EXTRA_STREAM, uri); Log.d("Mailer::sendMail", "java-code: sendMail(): 2"); Intent mailer = Intent.createChooser(intent, null); Log.d("Mailer::sendMail", "java-code: sendMail(): 3"); if(mailer == null){ Log.e("Mailer::sendMail", "Couldn't get Mail Intent"); return; } Log.d("Mailer", "java-code: mailer =" + mailer); Log.d("Mailer", "java-code: m_instance=" + m_instance); m_instance.getApplicationContext().startActivity(mailer); Log.d("Mailer::sendMail", "java-code: sendMail(): 4"); } catch (android.content.ActivityNotFoundException ex){ Log.e("Mailer", "catched android.content.ActivityNotFoundException while starting activity"); ex.printStackTrace(); } Log.d("Mailer", "java-code: notify(): END"); } } //My C++ function QAndroidJniObject javaFilenameStr = QAndroidJniObject::fromString(attachment); qDebug() << "call QAndroidJniObject::callStaticMethod to send " << attachment; QAndroidJniObject::callStaticMethod<void>( "com/company/myapp/JavaClass", "sendMail", "(Ljava/lang/String;)V", javaFilenameStr.object<jstring>()); //and a part of my AndroidManifest.xml <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="com.company.myapp.JavaClass" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
Currently, I think have a problem with this line
m_instance.getApplicationContext().startActivity(mailer);
Here are the output messagesĀ of the application when I run a first time my C++ function :
... D Mailer::sendMail: java-code: m_instance=com.company.myapp.JavaClass@8a067fd D Mailer::sendMail: java-code: sendMail(): 2 D Mailer::sendMail: java-code: sendMail(): 3 D Mailer : java-code: mailer =Intent { act=android.intent.action.CHOOSER (has extras) } D Mailer : java-code: m_instance=com.company.myapp.JavaClass@8a067fd
If I run a second time my function, the app crash with many messages including :
F art : art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: JNI NewString called with pending exception android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
What do you think aboutĀ ?
Thank you in advance.
Charlie.
-
@CharlieG The error message says it actually: you either start your activity from an activity context or set the FLAG_ACTIVITY_NEW_TASK flag (probably in m_instance.getApplicationContext().startActivity(mailer);). I'm not an android expert, so I cannot tell you what exactly you need to change.
-
Hi,
In fact, this is very easy :
Intent mailer = Intent.createChooser(intent, null); mailer.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Now I have to figure out how to do with the desktop device.
Unfortunately, for now, I can't run KService'sKToolInvocation :: invokMailer
function. -
Hi,
Sorry for the late response.
Any more details? can we help?
Maybe ;-)
In the first time, I wanted directly try the code of invokMailer in my app :
On Windows, here is the code :
... #include "shellapi.h" ... void KToolInvocation::invokeMailer(const QString &_to, const QString &_cc, const QString &_bcc, const QString &subject, const QString &body, const QString & /*messageFile TODO*/, const QStringList &attachURLs, const QByteArray &startup_id) { QUrl url(QLatin1String("mailto:") + _to); QUrlQuery query; query.addQueryItem(QStringLiteral("subject"), subject); query.addQueryItem(QStringLiteral("cc"), _cc); query.addQueryItem(QStringLiteral("bcc"), _bcc); query.addQueryItem(QStringLiteral("body"), body); foreach (const QString &attachURL, attachURLs) { query.addQueryItem(QStringLiteral("attach"), attachURL); } url.setQuery(query); #ifndef _WIN32_WCE QString sOpen = QLatin1String("open"); ShellExecuteW(0, (LPCWSTR)sOpen.utf16(), (LPCWSTR)url.url().utf16(), 0, 0, SW_NORMAL); #else SHELLEXECUTEINFO cShellExecuteInfo = {0}; cShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); cShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS; cShellExecuteInfo.hwnd = NULL; cShellExecuteInfo.lpVerb = L"Open"; cShellExecuteInfo.lpFile = (LPCWSTR)url.url().utf16(); cShellExecuteInfo.nShow = SW_SHOWNORMAL; ShellExecuteEx(&cShellExecuteInfo); #endif }
I can run the code, but the attachment isn't in the mail.
On Linux and Mac OSX, the function is replace by QDesktopService::openUrl(mailtoUrl). If I want directly use the code of invokeMailer, I have a problem with
include "shellapi.h"
So I turn around...
Have you an idea ?
Bye and thank.
Charlie