DelphiAndroid12 DelphiAndroid12 - 5 months ago 15
Android Question

Program hangs at TIdAttachmentFile constructor

I am writing an Android program using Delphi (Rad Studio 10.1) that will send data in a text file via email (using SMTP, etc.).

I am currently able to send email, but not with an attachment. The program appears to freeze when making the attachment file using the following code:

Attachment:=TIdAttachmentFile.Create(IdMessage1.MessageParts, (GetHomePath+'/test.txt'));


The path is not wrong because I am able to read the file to a memo using the following:

Memo2.Lines.LoadFromFile(GetHomePath+'/Test.txt');


Here is the entirety of my code related to the attachment:

Text := TIdText.Create(IdMessage1.MessageParts);
Text.ContentType := 'text/plain';
Text.Body.Add('Hello!');
Attachment := TIdAttachmentFile.Create(IdMessage1.MessageParts, (GetHomePath+'/test.txt'));
with Attachment do
begin
ContentType := 'text/plain';
FileName := 'test.txt';
end;
IdMessage1.ContentType := 'multipart/mixed';
AttMemory := TIdAttachmentMemory.Create(IdMessage1.MessageParts);


After this, I simply connect to a TIdSMTP and send the message. Again, there is no problem sending the email without the lines related to TIdAttachmentFile.

If I do include the line

AttMemory := TIdAttachmentMemory.Create(IdMessage1.MessageParts);


I get an email with an attachment, however, the attachment had no name, is empty, and cannot be related to the file I want to attach because to send the email, lines related to the attachment file must be commented out.

Answer

On this line:

Memo2.Lines.LoadFromFile(GetHomePath+'/Test');`

You are loading a file named Test, not test.txt. LoadFromFile() does not add a .txt file extension for you. The filename is used exactly as you provide it.

If that line really works, then you really do have a file named Test, and that is need to need to give to TIdAttachmentFile as well:

Attachment := TIdAttachmentFile.Create(IdMessage1.MessageParts, GetHomePath+'/Test');

You title claims the freeze happens in the TIdAttachmentFile constructor, but the constructor does not access the actual file yet, it just assigns a few property values (Filename, StoredPathName, FileIsTempFile, and ContentType). The file is not actually accessed until TIdSMTP.Send() needs to encode the file data. at which time, if a freeze is occuring, then either access to the file is being blocked, or network traffic is being blocked, or the like. Hard to diagnose that without debugging into Indy's source code to see exactly where the freeze is really occuring, as Send() performs many operations.

If Memo2.Lines.LoadFromFile() works, then an alternative would be to use TIdText instead of TIdAttachmentFile, so you can utilize the same LoadFromFile() method in the TIdText.Body property:

Text := TIdText.Create(IdMessage1.MessageParts, nil);
with Text do
begin
  Body.LoadFromFile(GetHomePath+'/Test');
  ContentType := 'text/plain';
  ContentDisposition := 'attachment';
  FileName := 'test.txt';
end; 

Either way, get rid of the TIdAttachmentMemory, it is not doing anything for you since you are not loading the file data into it.