Тут в процессе работы над одним проектом понадобилось узнать IP адрес устройства. Очень не хотелось включать дополнительные разрешения приложению. Думал ограничится одним "Доступ в Интернет".
Вот как это можно сделать:
С помощью TIdUDPServer посылаем широковещательное сообщение, с помощью того же TIdUDPServer сами получаем его и в ABinding узнаем с какого IP оно пришло. Таким образом мы узнаем IP адрес интерфейса с маршрутом по умолчанию.
Вот код, все просто:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
IdGlobal, IdSocketHandle, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer;
const ConstUDPSendString = 'dfgb2hd3f6gbf';
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FUDPServer : TIdUDPServer;
FMyIP : String;
procedure OnUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
procedure GetMyIP;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.FormCreate(Sender: TObject);
begin
GetMyIP;
end;
procedure TForm1.GetMyIP;
begin
FMyIP:='';
FUDPServer:=TIdUDPServer.Create;
FUDPServer.DefaultPort:=46734;
FUDPServer.BroadcastEnabled:=True;
FUDPServer.OnUDPRead:=OnUDPServerUDPRead;
FUDPServer.Active:=True;
FUDPServer.Broadcast(ConstUDPSendString, FUDPServer.DefaultPort);
end;
procedure TForm1.OnUDPServerUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
AThread.Synchronize(AThread,
procedure
begin
if BytesToString(AData).Equals(ConstUDPSendString) and FMyIP.IsEmpty then
FMyIP:=ABinding.PeerIP;
end
);
end;
end.