安卓中获取系统当前活动的网卡MAC地址和IP地址时,需要使用到java.net.networkinterface库,在Delphi中虽然可以调用java库,
但是如果没有现成的java库(jar、class等),也会比较麻烦,这里使用posix函数实现获取MAC和IP地址,不需要root权限,
但理论上应该需要设置查询网络状态和WIFI状态权限:
delphi的话在工程属性中勾选就好了。
使用posix函数的方法,理论上支持android、ios、mac、linux...好处是很多的,而在android的NDK开发中也是使用这种方法实现,网上找一下就有代码。
unit uNetWorkInfo;interface//注: posix的网络操作可参看indy控件的底层,如IdStackVCLPosix.pas// posix大部分操作可参看linux相关代码,搜索linux代码即可翻译成pascalfunction getLocalMac(var sIP: string): string;implementationuses Posix.Base, Posix.ArpaInet, Posix.Errno, Posix.NetDB, Posix.NetIf, Posix.NetinetIn, Posix.StrOpts, Posix.SysTypes, Posix.SysUio, Posix.Unistd, Posix.SysSelect, Posix.SysSocket, Posix.SysTime, Posix.Stdio, Sockios, SysUtils;type TSunB = packed record s_b1, s_b2, s_b3, s_b4: Byte; end; TSunW = packed record s_w1, s_w2: Word; end; PIn4Addr = ^TIn4Addr; TIn4Addr = packed record case integer of 0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: LongWord); end; PIn6Addr = ^TIn6Addr; TIn6Addr = packed record case Integer of 0: (s6_addr: packed array [0..16-1] of Byte); 1: (s6_addr16: packed array [0..8-1] of Word); end;function IPv4AddrToString(const aInAddr: TIn4Addr): string;begin Result := IntToStr(TIn4Addr(AInAddr).S_un_b.s_b1) + '.' { Do not Localize} + IntToStr(TIn4Addr(AInAddr).S_un_b.s_b2) + '.' { Do not Localize} + IntToStr(TIn4Addr(AInAddr).S_un_b.s_b3) + '.' { Do not Localize} + IntToStr(TIn4Addr(AInAddr).S_un_b.s_b4);end;// 获取本地macfunction getLocalMac(var sIP: string): string;{ $IFDEF POSIX}const MAXINTERFACES = 15;var sock_fd: integer; buf: array[0..MAXINTERFACES-1] of ifreq; ifc: ifconf; interface_num: integer; //M: TMarshaller; //sEn: string;{ $ENDIF}begin { $IFDEF POSIX} sIP := ''; Result := ''; sock_fd := socket(AF_INET, SOCK_DGRAM, //SOCK_STREAM, 0); if (sock_fd = -1) then begin //perror('create socket falise...mac\n'); Exit; end; FillChar(buf, SizeOf(buf), 0); ifc.ifc_len := sizeof(buf); ifc.ifc_ifcu.ifcu_req := @buf[0]; (* //sEn := 'eth0'; sEn := 'en0'; Move(M.AsAnsi(sEn).ToPointer^, ifr_mac.ifrn_name, 4); *) if(ioctl(sock_fd, SIOCGIFCONF, @ifc) < 0) then begin Exit; end; interface_num := ifc.ifc_len div sizeof(ifreq); while interface_num>0 do begin Dec(interface_num); sIP := ''; Result := ''; if (ioctl(sock_fd, SIOCGIFFLAGS, @buf[interface_num])<0) then begin Continue; end; (* if(buf[interface_num].ifr_flags & IFF_PROMISC) printf("Interface is in promiscuous mode\n"); *) if ((buf[interface_num].ifr_ifru.ifru_flags and IFF_UP)<>0) and ((buf[interface_num].ifr_ifru.ifru_flags and IFF_RUNNING)<>0)and ((buf[interface_num].ifr_ifru.ifru_flags and IFF_LOOPBACK)=0) then //printf("Interface is running\n"); else Continue; //printf("Interface is not running\n"); //IP地址 if (ioctl(sock_fd, SIOCGIFADDR, @buf[interface_num])<0) then begin Continue; end; if buf[interface_num].ifr_ifru.ifru_addr.sa_family<>AF_INET then //AF_INET6 Continue; sIP := IPv4AddrToString( TIn4Addr(sockaddr_in(buf[interface_num].ifr_ifru.ifru_addr).sin_addr)); //MAC地址 if ((ioctl(sock_fd, SIOCGIFHWADDR, @buf[interface_num])) < 0) then begin //printf('mac ioctl error\n'); Result := ''; Continue; end; Result := Format('%02X:%02X:%02X:%02X:%02X:%02X', [buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[0], buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[1], buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[2], buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[3], buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[4], buf[interface_num].ifr_ifru.ifru_hwaddr.sa_data[5]] ); Break; end; FileClose(sock_fd); { $ELSE} //其他平台(如Windows,网上已经有很多代码了,可自行补充) sIP := '0.0.0.0'; Result := '00:00:00:00:00:00'; { $ENDIF}end;end.
由于delphi XE5/XE7...没有翻译sockios.h文件,因此此文件中的常量定义需要补充,Sockios.pas如下:
unit Sockios;interfaceconst FIOSETOWN =$8901; SIOCSPGRP =$8902; FIOGETOWN =$8903; SIOCGPGRP =$8904; SIOCATMARK =$8905; SIOCGSTAMP =$8906; //SIOCINQ = FIONREAD; //SIOCOUTQ = TIOCOUTQ; SIOCADDRT =$890B; SIOCDELRT =$890C; SIOCRTMSG =$890D; SIOCGIFNAME =$8910; SIOCSIFLINK =$8911; SIOCGIFCONF =$8912; SIOCGIFFLAGS =$8913; SIOCSIFFLAGS =$8914; SIOCGIFADDR =$8915; SIOCSIFADDR =$8916; SIOCGIFDSTADDR =$8917; SIOCSIFDSTADDR =$8918; SIOCGIFBRDADDR =$8919; SIOCSIFBRDADDR =$891a; SIOCGIFNETMASK =$891b; SIOCSIFNETMASK =$891c; SIOCGIFMETRIC =$891d; SIOCSIFMETRIC =$891e; SIOCGIFMEM =$891f; SIOCSIFMEM =$8920; SIOCGIFMTU =$8921; SIOCSIFMTU =$8922; SIOCSIFNAME =$8923; SIOCSIFHWADDR =$8924; SIOCGIFENCAP =$8925; SIOCSIFENCAP =$8926; SIOCGIFHWADDR =$8927; SIOCGIFSLAVE =$8929; SIOCSIFSLAVE =$8930; SIOCADDMULTI =$8931; SIOCDELMULTI =$8932; SIOCGIFINDEX =$8933; SIOGIFINDEX =SIOCGIFINDEX; SIOCSIFPFLAGS =$8934; SIOCGIFPFLAGS =$8935; SIOCDIFADDR =$8936; SIOCSIFHWBROADCAST =$8937; SIOCGIFCOUNT =$8938; SIOCKILLADDR =$8939; SIOCGIFBR =$8940; SIOCSIFBR =$8941; SIOCGIFTXQLEN =$8942; SIOCSIFTXQLEN =$8943; SIOCETHTOOL =$8946; SIOCGMIIPHY =$8947; SIOCGMIIREG =$8948; SIOCSMIIREG =$8949; SIOCWANDEV =$894A; SIOCDARP =$8953; SIOCGARP =$8954; SIOCSARP =$8955; SIOCDRARP =$8960; SIOCGRARP =$8961; SIOCSRARP =$8962; SIOCGIFMAP =$8970; SIOCSIFMAP =$8971; SIOCADDDLCI =$8980; SIOCDELDLCI =$8981; SIOCGIFVLAN =$8982; SIOCSIFVLAN =$8983; SIOCBONDENSLAVE =$8990; SIOCBONDRELEASE =$8991; SIOCBONDSETHWADDR =$899; SIOCBONDSLAVEINFOQUERY =$8993; SIOCBONDINFOQUERY =$8994; SIOCBONDCHANGEACTIVE =$8995; SIOCBRADDBR =$89a0; SIOCBRDELBR =$89a1; SIOCBRADDIF =$89a2; SIOCBRDELIF =$89a3; SIOCDEVPRIVATE =$89F0; SIOCPROTOPRIVATE =$89E0;implementationend.