安卓中獲取系統當前活動的網卡MAC地址和IP地址時,須要使用到java.net.networkinterface庫,在Delphi中雖然能夠調用java庫,java
可是若是沒有現成的java庫(jar、class等),也會比較麻煩,這裏使用posix函數實現獲取MAC和IP地址,不須要root權限,linux
但理論上應該須要設置查詢網絡狀態和WIFI狀態權限:android
<!-- 獲取網絡狀態的權限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
delphi的話在工程屬性中勾選就行了。ios
使用posix函數的方法,理論上支持android、ios、mac、linux...好處是不少的,而在android的NDK開發中也是使用這種方法實現,網上找一下就有代碼。網絡
unit uNetWorkInfo; interface //注: posix的網絡操做可參看indy控件的底層,如IdStackVCLPosix.pas // posix大部分操做可參看linux相關代碼,搜索linux代碼便可翻譯成pascal function getLocalMac(var sIP: string): string; implementation uses 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; // 獲取本地mac function 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以下:socket
unit Sockios; interface const 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; implementation end.