【问题标题】:How to create a folder and a txt file in DelphiDelphi中如何创建文件夹和txt文件
【发布时间】:2019-07-31 06:30:32
【问题描述】:

如何在 Android 的内部存储 (?) 中创建一个新文件夹(我想说,主文件夹包含所有子文件夹...Whatsapp、DCIM、图片、铃声、警报 ..) 并在此文件夹中创建一个新的 .txt 文件。

我想创建一个.txt 文件,我需要用户将 USB 电缆插入他们的计算机,访问设备,输入我的应用程序创建的文件夹,然后将此文件复制到他们的桌面。

我尝试了这段代码来创建文件:

procedure TF_start.Button2Click(Sender: TObject);
var
  output_text: string;
  arquivo: TextFile;
begin
  output_text := 'test';

  TFile.WriteAllText(TPath.Combine(TPath.GetDocumentsPath, 'test.txt'), 'content');

  ReWrite(arquivo);

  WriteLn(arquivo, output_text);

  CloseFile(arquivo);

end;

但它不起作用。

为了获取内部存储(?)路径,我找到了这段代码:

P := '/storage/';
if (FindFirst(P + '*', faAnyFile, Sr) = 0) then
  repeat
    Memo1.Lines.Add(Sr.Name);
  until (FindNext(Sr) <> 0);
FindClose(Sr);

但我无法理解它是如何工作的,所以我什至无法使用它。

我还找到了this link,但我没有找到任何返回我想要创建文件夹的“常规”目录路径的函数。

函数System.IOUtils.TPath.GetHomePath()System.IOUtils.TPath.GetDocumentsPath() 不会返回正确的路径。

System.SysUtils.GetHomePath() 返回 -> /data/user/0/com.embarcadero.app/cache

System.IOUtils.TPath.GetDocumentsPath() 返回 -> /data/com.embarcadero.app-1/lib/arm

@编辑

使用@Remy Lebeau 代码和this code 我设法做到了这一点。 问题是用文件更新目录的代码什么都不做

Use System.IOUtils, Androidapi.Helpers, Androidapi.Jni.Media, Androidapi.JNI.JavaTypes, Androidapi.JNI.GraphicsContentViewText;

//按钮

procedure TF_start.Button2Click(Sender: TObject);
var
  path_file output_text: string;
begin
  path_file := TPath.Combine(System.IOUtils.TPath.GetSharedDownloadsPath, 'Folder_app');
  output_text := 'test';
  if not TDirectory.Exists(path_file) then
    TDirectory.CreateDirectory(path_file);

  try
    TFile.WriteAllText(TPath.Combine(path_file, Nome_Arquivo), Arquivo_saida);
  except
    ShowMessage('An error occurred while saving the file.');
  end;
end;

另一个按钮:

procedure TF_corrida.BTNfinalize_appClick(Sender: TObject);
var
  c: Integer;
  JMediaScannerCon: Androidapi.Jni.Media.JMediaScannerConnection;
  JMediaScannerCon_Client: Androidapi.Jni.Media.JMediaScannerConnection_MediaScannerConnectionClient;
begin
    JMediaScannerCon:=TJMediaScannerConnection.JavaClass.init(TAndroidHelper.Context, JMediaScannerCon_Client);
    JMediaScannerCon.connect;
    c:=0;
    while not JMediaScannerCon.isConnected do begin
      Sleep(100);
      inc(c);
      if (c>20) then break;
    end;
    if (JMediaScannerCon.isConnected) then begin
      JMediaScannerCon.scanFile(StringToJString(path_file), nil);
      JMediaScannerCon.disconnect;
    end;
end;

PS 这个警告出现了:

[DCC 警告] u_corrida.pas(682): W1000 符号“SharedActivityContext” 已弃用:'使用 TAndroidHelper.Context'

所以我改了代码

注意:我也尝试将“path_file”替换为“System.IOUtils.TPath.GetSharedDownloadsPath”,但也无济于事

此问题已回答,其他问题(索引文件和文件夹)已移至:How to index a created file in Android sdcard Delphi

【问题讨论】:

  • "为了获取内部存储(?)路径,我找到了这段代码……但我无法理解它是如何工作的,所以我什至无法使用它。 i>" - 在这种情况下它对你没有帮助。它所做的只是枚举/storage/ 文件夹本身,在TMemo 中显示文件和子文件夹的名称。
  • 到目前为止,我正在研究为什么 ScanFile 不起作用,到目前为止我还没有找到答案。如果有人可以帮助我,我将不胜感激

标签: delphi firemonkey


【解决方案1】:

您实际上并不想要“内部存储”,它是您的应用程序私有的,甚至用户也无法访问它(没有对设备的 root 访问权限)。您需要“外部存储”,以便用户(和其他应用程序)可以访问它。

根据 Android 文档中的 Save files on device storage

当您想确保用户或其他应用都无法访问您的文件时,最好使用内部存储。

外部存储是存储不需要访问限制的文件以及您希望与其他应用共享或允许用户通过计算机访问的文件的最佳位置。

使用TPath.GetShared...() 方法之一获取“外部存储”路径,例如TPath.GetSharedDocumentsPath()。并确保您的应用启用了WRITE_EXTERNAL_STORAGE 权限。

另外,请注意TFile.WriteAllText() 不会创建丢失的文件夹(实际上,它会引发EDirectoryNotFoundException)。您必须先自己创建文件夹,例如使用TDirectory.CreateDirectory()SysUtils.ForceDirectories()TPath.Combine() 只是将输入字符串连接在一起,它不会创建实际的文件夹。

试试这个:

procedure TF_start.Button2Click(Sender: TObject);
var
  path, output_text: string;
begin
  output_text := 'test';
  path := TPath.Combine(TPath.GetSharedDocumentsPath, 'myfolder');
  if not TDirectory.Exists(path) then
    TDirectory.CreateDirectory(path);
  TFile.WriteAllText(TPath.Combine(path, 'test.txt'), output_text);
end;

【讨论】:

  • 这非常适合创建文件夹和文件,但最大的问题是它在“文档”文件夹中创建了文件夹,并且通过 USB 电缆看不到该文件夹​​。理想情况下,在与文档文件夹相同的位置创建一个文件夹,而不是在其中。可以这样做吗?
  • 如果我不能,那很好,我可以在“下载”文件夹中创建我想要的文件夹和文件。当我通过电话访问时,我可以找到创建的文件夹和文件,但是当我通过计算机访问时,我找不到它们......你知道会发生什么吗?在我的手机上,它位于“/storage/emulated/0/Downloads/myfolder/test.txt”,但如果我去我的电脑,下载文件夹是空的
  • 1天后文件夹出现..为什么要这么长时间?
  • 但如果不是 Delphi 代码,我该如何使用“mediaScannerConnection.scanFile”?事实上,我从来没有理解过使用其他代码的这种关系。有没有我可以声明使用的单位?