androiddelphiandroid-intentfiremonkeydelphi-xe7

How to send email with attachment using default Android email app - Delphi XE7


Using code below which I found on another post, the email appears ready to send with the attachment, but when email is received, there is no attachment. Also, the email address has to be manually entered, it is not populated by the CreateEmail statement. I am sending from a gmail account. Anyone help please?

procedure TForm1.CreateEmail(const Recipient, Subject, Content,
 Attachment: string);
var
 Intent: JIntent;
 Uri: Jnet_Uri;
 AttachmentFile: JFile;
begin
 Intent := TJIntent.Create;
 Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
 Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
 Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, StringToJString(Recipient));
 Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(Subject));
 Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(Content));
 AttachmentFile := SharedActivity.getExternalFilesDir
   (StringToJString(Attachment));

 Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile);

 Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM,
   TJParcelable.Wrap((Uri as ILocalObject).GetObjectID));

 Intent.setType(StringToJString('vnd.android.cursor.dir/email'));

 SharedActivity.startActivity(Intent);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 CreateEmail('xxx@shaw.ca', 'Test Results', Memo1.Lines.text,'/sdcard/Download/Demo.pdf');
end;

Solution

  • Intent.EXTRA_EMAIL is documented as expecting an array of string values, but you are passing it a single string instead.

    You are also not using SharedActivity.getExternalFilesDir() correctly. Its type parameter specifies the type of folder you want to lookup (MUSIC, PODCASTS, PICTURES, etc), and then it returns a JFile that represents that folder. You can then append a filename to the path of that folder as needed. However, in this case, your Attachment string contains a full path to the actual file that you want to attach, so you should not be calling getExternalFilesDir() at all. Create a JFile from the path as-is instead.

    Try this:

    procedure TForm1.CreateEmail(const Recipient, Subject, Content, Attachment: string);
    var
      JRecipient: TJavaObjectArray<JString>;
      Intent: JIntent;
      Uri: Jnet_Uri;
      AttachmentFile: JFile;
    begin
      JRecipient := TJavaObjectArray<JString>.Create(1);
      JRecipient.Items[0] := StringToJString(Recipient);
    
      Intent := TJIntent.Create;
      Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
      Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
      Intent.putExtra(TJIntent.JavaClass.EXTRA_EMAIL, JRecipient);
      Intent.putExtra(TJIntent.JavaClass.EXTRA_SUBJECT, StringToJString(Subject));
      Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(Content));
    
      if Attachment <> '' then
      begin
        AttachmentFile := TJFile.JavaClass.init(StringToJString(Attachment));
        Uri := TJnet_Uri.JavaClass.fromFile(AttachmentFile);
        Intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, TJParcelable.Wrap((Uri as ILocalObject).GetObjectID));
      end;
    
      Intent.setType(StringToJString('vnd.android.cursor.dir/email'));
    
      SharedActivity.startActivity(Intent);
    end;
    

    Read this article for more details about sending emails in Android:

    Launching activities and handling results in Delphi XE5 Android apps | Sending an email