{$mode delphi}
unit unit1;
interface
uses
Classes, SysUtils, And_jni, And_jni_Bridge, Laz_And_Controls,
Laz_And_Controls_Events, AndroidWidget, opendialog, blcksock,
uTCPSockets, uTCPCryptoCompression,fileutil;
type
{ TAndroidModule1 }
TAndroidModule1 = class(jForm)
jAsyncTask1: jAsyncTask;
jButton1: jButton;
jButton2: jButton;
jButton3: jButton;
jEditText1: jEditText;
jEditText2: jEditText;
jOpenDialog1: jOpenDialog;
procedure AndroidModule1JNIPrompt(Sender: TObject);
procedure AndroidModule1RequestPermissionResult(Sender: TObject;
requestCode: integer; manifestPermission: string;
grantResult: TManifestPermissionResult);
procedure jAsyncTask1DoInBackground(Sender: TObject; progress: integer; out
keepInBackground: boolean);
procedure jAsyncTask1PostExecute(Sender: TObject; progress: integer);
procedure jButton1Click(Sender: TObject);
procedure jButton2Click(Sender: TObject);
procedure jButton3Click(Sender: TObject);
procedure jOpenDialog1FileSelected(Sender: TObject; path: string;
fileName: string);
private
public
{public declarations}
function SendMessage(AMsg: String; AParams: array of String): Boolean;
function RecvMessage(ATimeOut: Integer; out AMsgTyp: Integer; out AMsg: String; out AParams: TStringArray): Boolean;
procedure DoError(AErrMsg: String; AErrCode: Integer);
function DoTask(Progress: integer): boolean;
function SendFile(AFileName: String): Boolean;
end;
var
AndroidModule1: TAndroidModule1;
FBlockSocket : TTCPBlockSocket;
MsgTyp:integer;
Msg:string;
Params:tstringarray;
implementation
{$R *.lfm}
//To connect to the GetMem server
procedure TAndroidModule1.jButton1Click(Sender: TObject);
begin
FBlockSocket := TTCPBlockSocket.Create;
FBlockSocket.Connect ('172.26.61.98', '53771');
//the ip here is a node of a network I created with Zerotier.
// No password in server . Please
FBlockSocket.SendString (encrypt('53771','0LOGIN:,User,0,') );
repeat
until RecvMessage(500, MsgTyp, Msg, Params) ;
jEditText2.Text :=Params[0];
jAsyncTask1.Execute ;
end;
// send text message :
procedure TAndroidModule1.jButton2Click(Sender: TObject);
begin
SendMessage('0TEXT', [jEditText1.Text]);
End;
//Choose a file
procedure TAndroidModule1.jButton3Click(Sender: TObject);
begin
jOpenDialog1.Show();
end;
//Send file
procedure TAndroidModule1.jOpenDialog1FileSelected(Sender: TObject;
path: string; fileName: string);
begin
SendMessage('2FILE', ['FILE',inttostr( fileutil.FileSize(path+'/'+fileName)),fileName]);
SendFile(path+'/'+fileName);
end;
//GetMem Code Functions
function TAndroidModule1.SendFile(AFileName: String): Boolean;
var
ReadCnt: LongInt;
Cnt: Int64;
Buffer: Pointer;
MS: TMemoryStream;
MSComp: TMemoryStream;
FS: TFileStream;
Msg: String;
CompRate: Single;
begin
Result := False;
try
FS := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
try
FS.Position := 0;
GetMem(Buffer, FBlockSocket.SendMaxChunk);
try
Cnt := 0;
MS := TMemoryStream.Create;
try
MSComp := TMemoryStream.Create;
try
repeat
Msg := FBlockSocket.RecvPacket(50000);
if (FBlockSocket.LastError > 0) or (Msg = 'DONE') or (Msg <> 'NEXT') then
Break;
ReadCnt := FS.Read(Buffer^, FBlockSocket.SendMaxChunk);
if (ReadCnt > 0) then
begin
MS.Clear;
MS.Write(Buffer^, ReadCnt);
MS.Position := 0;
FBlockSocket.SendStream(MS);
if (FBlockSocket.LastError = 0) then
begin
Cnt := Cnt + MS.Size;
end;
end;
until (ReadCnt = 0) or (Cnt > FS.Size);
Result := FBlockSocket.LastError = 0;
if Result then showmessage(inttostr(FS.Size))
else showmessage('erro');
finally
MSComp.Free;
end;
finally
MS.Free;
end;
finally
FreeMem(Buffer);
end;
finally
FS.Free;
end;
except
on E: Exception do
showmessage('erro');
end
end;
function TAndroidModule1.SendMessage(AMsg: String; AParams: array of String): Boolean;
var
I: Integer;
Msg: String;
begin
Result := False;
Msg := AMsg;
if Length(AParams) > 0 then
begin
AMsg := AMsg + ':';
for I := Low(AParams) to High(AParams) do
AMsg := AMsg + AParams[I] + ',';
end;
AMsg := Encrypt('53771', AMsg);
FBlockSocket.SendString(AMsg);
Result := FBlockSocket.LastError = 0;
Delete(Msg, 1, 1);
if Result then
showmessage('Send')
else
showmessage('error');
end;
function TAndroidModule1.RecvMessage(ATimeOut: Integer; out AMsgTyp: Integer;
out AMsg: String; out AParams: TStringArray): Boolean;
var
Str: String;
P: Integer;
Len: Integer; var m:tmemorystream;
begin
Result :=true;
AMsg := '';
AMsgTyp := -1;
AParams := nil;
Str := FBlockSocket.RecvPacket(ATimeOut);
if (FBlockSocket.LastError > 0) then
begin
Result := False;
Exit;
end;
if Trim(Str) <> '' then
begin
Str := Decrypt('53771', Str);
P := Pos(':', Str);
if P > 0 then
begin
AMsg := Trim(System.Copy(Str, 1, P - 1));
System.Delete(Str, 1, P);
repeat
P := Pos(',', Str);
if P > 0 then
begin
Len := Length(AParams);
SetLength(AParams, Len + 1);
AParams[Len] := System.Copy(Str, 1, P - 1);
System.Delete(Str, 1, P);
end;
until (P = 0) or (Str = '') ;
end
else
AMsg := Trim(Str);
AMsgTyp := StrToIntDef(AMsg[1], -1);
if (not AMsgTyp in [0..3]) then
begin
jEditText2.Text :='Error';
Result := False;
Exit;
end;
Delete(AMsg, 1, 1);
end;
end;
//jAsyncTask
function TAndroidModule1.DoTask(Progress: integer): boolean;
begin
Result:= True;
repeat
until RecvMessage(500, MsgTyp, Msg, Params) ;
Result:= False;
end;
procedure TAndroidModule1.jAsyncTask1DoInBackground(Sender: TObject;
progress: integer; out keepInBackground: boolean);
begin
keepInBackground:= DoTask(progress);
end;
procedure TAndroidModule1.jAsyncTask1PostExecute(Sender: TObject;
progress: integer);
begin
jAsyncTask1.Done;
jEditText2.Text :=Params[0];
jAsyncTask1.Execute;
end;
procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);
var
manifestPermissions: TDynArrayOfString;
begin
if IsRuntimePermissionNeed() then // that is, target API >= 23
begin
SetLength(manifestPermissions, 3);
manifestPermissions[1]:= 'android.permission.WRITE_EXTERNAL_STORAGE'; //from AndroodManifest.xml
Self.RequestRuntimePermission(manifestPermissions, 1001);
SetLength(manifestPermissions, 0);
end;
end;
procedure TAndroidModule1.AndroidModule1RequestPermissionResult(
Sender: TObject; requestCode: integer; manifestPermission: string;
grantResult: TManifestPermissionResult);
begin
case requestCode of
1001:begin
if grantResult = PERMISSION_GRANTED then
exit;
end;
end;
end;
// insert as the code asks for jButton jEditText jAsyncTask
// And of course, declare variables etc as the code asks for
// don't forget the necessary permissions.