使用 Delphi 11 将文件从 Android 设备上传到远程服务器

问题描述 投票:0回答:1

我想创建一个简单的 Android 应用程序。应用程序应使用文件选择器浏览文件,选择 PDF 文件,在编辑中显示其路径或仅显示名称,然后通过 HTTP 将其发送到远程服务器。

TIdHTTP
组件应该可以做到这一点。

我自己尝试过,我问过ChatGPT,我到处找,但我找不到示例或类似的代码。

我尝试了ChatGPT代码,但它不起作用,它提出了3个程序:

  1. 打开文件选择器
  2. 从 URI 获取文件名
  3. 上传文件

我唯一理解的是第三个,它不起作用,因为它尝试创建 PDF 文件流,但无法创建它。

java android http delphi
1个回答
-1
投票
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.Layouts , IdHTTP , IdMultipartFormData , FMX.Edit, Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Net, Androidapi.Helpers, Androidapi.JNI.JavaTypes , FMX.Memo.Types,FMX.ScrollBox, FMX.Memo, System.Messaging,

  Androidapi.JNI.Os, Androidapi.JNI.App, FMX.Objects, System.IOUtils,
  Androidapi.JNI.Widget, FMX.TabControl, Androidapi.JNI.Provider,
  FMX.Platform.Android,
  Androidapi.JNIBridge, FMX.Surfaces, FMX.Helpers.Android, Androidapi.JNI.Media,
  Androidapi.JNI.Webkit, Androidapi.Jni, Posix.Unistd, Androidapi.JNI.Support,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient ;

type
  TForm1 = class(TForm)
    Layout1: TLayout;
    Layout2: TLayout;
    Layout3: TLayout;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Button3: TButton;
    IdHTTP1: TIdHTTP;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure GetPermissions(Sender: TObject);
     procedure ShowFileChooser;
   
  private
    { Private declarations }


  public
    { Public declarations }
    Intent: JIntent;
    Uri: Jnet_Uri;
    FilePath: string;
    procedure HandleActivityResult(const Sender: TObject; const M: TMessage);
    function GetSelectedFilePathFromUri(Uri: Jnet_Uri): string;


  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}
 uses system.Permissions ;

procedure TForm1.GetPermissions(Sender: TObject);
const
  PermissionReadExStrg = 'android.permission.READ_EXTERNAL_STORAGE';
  PermissionMakeCalls = 'android.permission.CALL_PHONE';
begin

          {$IFDEF ANDROID}
          PermissionsService.RequestPermissions([PermissionReadExStrg],
          procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
           begin
             if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
              { activate or deactivate the location sensor }

             else
              begin

               ShowMessage('permission not granted');
          end;
        end);


{$ENDIF}

 {$IFDEF ANDROID}
          PermissionsService.RequestPermissions([PermissionMakeCalls],
          procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
           begin
             if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
              { activate or deactivate the location sensor }

             else
              begin

               ShowMessage('permission not granted');
          end;
        end);


{$ENDIF}


end;



procedure TForm1.Button1Click(Sender: TObject);
{var
  Intent: JIntent; }
 const  PermissionReadExStrg = 'android.permission.READ_EXTERNAL_STORAGE';
begin
 if not PermissionsService.IsPermissionGranted(JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE)) then
  begin
       PermissionsService.RequestPermissions([PermissionReadExStrg],
          procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
           begin
             if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
              { activate or deactivate the location sensor }
               ShowFileChooser
             else
              begin

               ShowMessage('permission not granted');
          end;
        end);
  end
  else
  ShowFileChooser;

 end;

 function TForm1.GetSelectedFilePathFromUri(Uri: Jnet_Uri): string;
var
  Cursor: JCursor;
  ColumnIndex: Integer;
begin
  // Content URI scheme (e.g., content://media/external/images/media/1234)
  if JStringToString(Uri.getScheme) = 'content' then
  begin
    Cursor := SharedActivity.getContentResolver.query(Uri, nil, nil, nil, nil);
    if Cursor <> nil then
    begin
      try
        if Cursor.moveToFirst then
        begin
          ColumnIndex := Cursor.getColumnIndex(TJMediaStore_MediaColumns.JavaClass.DATA);
          Result := JStringToString(Cursor.getString(ColumnIndex));
        end
        else
          Result := ''; // No data found
      finally
        Cursor.close;
      end;
    end
    else
      Result := ''; // Cursor is nil
  end
  // File URI scheme (e.g., file:///storage/emulated/0/Download/file.pdf)
  else if JStringToString(Uri.getScheme) = 'file' then
    Result := JStringToString(Uri.getPath)
  else
    Result := ''; // Unsupported URI scheme
end;







  procedure TForm1.ShowFileChooser;
{var
  Intent: JIntent;
  m:TMessageResultNotification; }
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT);
  Intent.setType(StringToJString('application/pdf'));
  SharedActivity.startActivityForResult(Intent, 0);

end;

procedure TForm1.HandleActivityResult(const Sender: TObject; const M: TMessage);
var
  RequestCode, ResultCode: Integer;


begin
    //  edit1.Text:= Jstringtostring(Intent.toURI);

  if M is TMessageResultNotification then
  begin
    RequestCode := TMessageResultNotification(M).RequestCode;
    ResultCode := TMessageResultNotification(M).ResultCode;
    Intent := TMessageResultNotification(M).Value;
    edit1.Text:=Jstringtostring(intent.getData.getScheme);
    if (RequestCode = 0) and (ResultCode = TJActivity.JavaClass.RESULT_OK) then
    begin
      Uri := Intent.getData;
      if Uri <> nil then
      begin
        FilePath := GetSelectedFilePathFromUri(Uri);
        // Use FilePath as needed (e.g., display in Edit control)
        Edit1.Text := Jstringtostring(uri.toString);
      end
      else
        ShowMessage('Failed to get file path');
    end;
  end;
end;



procedure TForm1.Button2Click(Sender: TObject);
var
  HTTP: TIdHTTP;
  FormData: TIdMultiPartFormDataStream;
begin
  if Edit1.Text = '' then
  begin
    ShowMessage('Please select a file.');
    Exit;
  end
  else
  begin

  HTTP :=  TIdHTTP.Create(self);
  FormData := TIdMultiPartFormDataStream.Create;
  try
       FormData.AddFile('file', Edit1.Text, 'application/pdf');
     showmessage(formdata.Size.ToString);
    HTTP.Post('MY_SERVER', FormData);
    ShowMessage('File uploaded successfully.');
  except
    on E: Exception do
      ShowMessage('Error uploading file: ' + E.Message);
  end;
  FormData.Free;
  HTTP.Free;
  end;
end.

这是chat gpt提出的代码 我有 2 个按钮搜索文件和上传文件 和编辑。 它应该打开文件选择器“它做得正确” 当我选择一个文件时,它会在编辑中显示其名称“不工作,编辑始终为空” 当我点击上传按钮时,它说“无法发送‘空’

© www.soinside.com 2019 - 2024. All rights reserved.