qubits 20 Posted March 14, 2022 GStack,LocalAddress does not work on Android. I am already getting WifiManager to obtain a lock, so I pulled the ip out of it. info := fWifiManager.getConnectionInfo; ip := MakeDWordIntoIPv4Address(info.getIpAddress); fIp:=ip; works perfect but all backwards. looked but, is there another routine i can run the longword thru before converting to a string or something?? sorry, thanks.. q Share this post Link to post
Dave Nottage 563 Posted March 14, 2022 14 minutes ago, qubits said: GStack,LocalAddress does not work on Android. You're welcome to use the code from here: https://github.com/DelphiWorlds/Multicaster/blob/master/MC.LocalAddresses.Android.pas Code repeated here in case that repo ever "disappears": unit MC.LocalAddresses.Android; interface uses IdStack; procedure GetLocalAddressList(const AAddresses: TIdStackLocalAddressList); implementation uses // RTL System.SysUtils, // Android Androidapi.JNI.Java.Net, Androidapi.JNI.JavaTypes, Androidapi.Helpers, Androidapi.JNIBridge, // Indy IdGlobal; procedure GetLocalAddressList(const AAddresses: TIdStackLocalAddressList); var LInterfaces, LAddresses: JEnumeration; LInterface: JNetworkInterface; LAddress: JInetAddress; LName, LHostAddress: string; begin AAddresses.Clear; LInterfaces := TJNetworkInterface.JavaClass.getNetworkInterfaces; while LInterfaces.hasMoreElements do begin LInterface := TJNetworkInterface.Wrap(JObjectToID(LInterfaces.nextElement)); LAddresses := LInterface.getInetAddresses; while LAddresses.hasMoreElements do begin LAddress := TJInetAddress.Wrap(JObjectToID(LAddresses.nextElement)); if LAddress.isLoopbackAddress then Continue; // Hack until I can find out how to check properly LName := JStringToString(LAddress.getClass.getName); LHostAddress := JStringToString(LAddress.getHostAddress); // Trim excess stuff if LHostAddress.IndexOf('%') > -1 then LHostAddress := LHostAddress.Substring(0, LHostAddress.IndexOf('%')); if LName.Contains('Inet4Address') then TIdStackLocalAddressIPv4.Create(AAddresses, LHostAddress, '') else if LName.Contains('Inet6Address') then TIdStackLocalAddressIPv6.Create(AAddresses, LHostAddress); end; end; end; end. Note: this code hasn't been changed in some time. The "hack" can probably be done another way, and I'm pretty sure Yaroslav has told me JObjectToID isn't necessary 1 Share this post Link to post
qubits 20 Posted March 14, 2022 (edited) flipped it around just now.. with this.. function SwapBytes(Value: LongWord): LongWord; type Bytes = packed array[0..3] of Byte; begin Bytes(Result)[0]:= Bytes(Value)[3]; Bytes(Result)[1]:= Bytes(Value)[2]; Bytes(Result)[2]:= Bytes(Value)[1]; Bytes(Result)[3]:= Bytes(Value)[0]; end; info := fWifiManager.getConnectionInfo; lw:=info.getIpAddress; lw:=SwapBytes(lw); ip := MakeDWordIntoIPv4Address(lw); fIp:=ip; fixed me up nicely.. i have already seen that getting ip from wifimanager is no longer appreciated.. so yes, i'll give that example a testing too, thanks!! Indy Packet Server - work in progress ~q Edited March 14, 2022 by qubits Share this post Link to post
Remy Lebeau 1436 Posted March 14, 2022 (edited) 15 hours ago, qubits said: GStack,LocalAddress does not work on Android. GStack.LocalAddress is deprecated, you should be using GStack.GetLocalAddressList() instead. Quote I am already getting WifiManager to obtain a lock, so I pulled the ip out of it. Indy does not currently use WifiManager, that operates at the Android Java layer, but since Indy operates at the native layer then it uses Linux APIs instead to enumerate local IPs, namely gethostname()+getaddrinfo() (there is a TODO in IdStackVCLPosix.pas to use getifaddrs() instead, or Android's NetworkInterface or WifiManager). Quote info := fWifiManager.getConnectionInfo; ip := MakeDWordIntoIPv4Address(info.getIpAddress); fIp:=ip; works perfect but all backwards. MakeDWordIntoIPv4Address() is deprecated, use MakeUInt32IntoIPv4Address() instead. Alternatively, have a look at TIdIPAddress.IPv4(AsString) (which uses MakeUInt32IntoIPv4Address() internally). But in any case, the input value is expected to be in network byte order, aka big endian, but WifiInfo.getIpAddress() returns an IPv4 address in host byte order, which may be either little endian or big endian, depending on the device. You can use Integer.reverseBytes() to swap the IP's endian if ByteOrder.nativeOrder() is LITTLE_ENDIAN. Seems Indy's own use of MakeUInt32IntoIPv4Address() may be inconsistent, some places use host byte order, some don't. Also, WifiInfo.getIpAddress() is deprecated since Android 12. You should use LinkProperties now. Edited March 14, 2022 by Remy Lebeau Share this post Link to post