djnacho djnacho - 1 month ago 27
Android Question

Delphi XE6 and Android Ping

I want to ping to a server with indy component TidIcmpClient in Android plattform but the debugger stops the code with a "Socket Error #1". The code is in a separate thread, so i post here the thread code:

procedure TEco.Execute;

var
contadoreco: Cardinal;
buffer: string;

begin
buffer:='12345678901234567890123456789012';
eco:=TIdIcmpClient.Create(nil);
for contadoreco:=1 to 4 do
begin
with eco do
begin
ReceiveTimeout:=2000;
Host:=servidor;
PacketSize:=32;
Ping(buffer,contadoreco);
ipservidor:=ReplyStatus.FromIpAddress;
end;
Synchronize(procedure
begin
Form1.StringGrid1.Cells[0,contadoreco]:=ipservidor;
Form1.StringGrid1.Cells[1,contadoreco]:=IntToStr(tiempoeco);
end);
end;
eco.Free;
end;


The TEco object is declared here:

TEco = class(TThread)
private
servidor: string;
eco: TIdIcmpClient;
terminado: Boolean;
tiempoeco: Cardinal;
ipservidor: string;
protected
procedure Execute; override;
end;


How i can ping a server with TidIcmpClient in Android? Am i doing something wrong? Superuser rights or some so? Thanks in advance for help me, and sorry for poor english. I expect you understand my question ;) :)

Answer

TIdIcmpClient uses a RAW socket, which requires admin/root access on most systems, including Android.

There are two ways to perform a ping in Android using Android's own APIs:

  1. use the isReachable() method of the InetAddress class. However, apparently this does not work correctly.

  2. Use java.lang.ProcessBuilder() to spawn /system/bin/ping. In fact, the java.lang.Process documentation shows an example of that. The downside is that you would have to manually parse the output.

Either solution would require you to use Delphi's JNI wrapper to access the relevant Android APIs.

Comments