Delphi For Android 使用Posix函数获取网络信息(MAC, IP...)

安卓中获取系统当前活动的网卡MAC地址和IP地址时,需要使用到java.net.networkinterface库,在Delphi中虽然可以调用java库,

但是如果没有现成的java库(jar、class等),也会比较麻烦,这里使用posix函数实现获取MAC和IP地址,不需要root权限,

但理论上应该需要设置查询网络状态和WIFI状态权限:

<!-- 获取网络状态的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

delphi的话在工程属性中勾选就好了。

使用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如下:

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.
时间: 2024-10-27 04:06:12

Delphi For Android 使用Posix函数获取网络信息(MAC, IP...)的相关文章

借助Sigar API获取网络信息

Sigar(全称System Information Gatherer And Reporter,即系统信息收集报表器),它提供了一个开源的跨平台的收集计算机硬件和操作系统信息的API(该API底层接口用C语言编写),本文将演示如何借助Sigar API获取网络信息: package com.ghj.packageoftest; import org.hyperic.sigar.NetFlags; import org.hyperic.sigar.NetInterfaceConfig; impo

Xamarin.Android 使用百度地图获取定位信息

最近做一个项目,web端使用百度地图,PDA使用手持机自带的GPS定位系统获取经纬度,然后再百度地图上显示该经纬度会有一定距离的差异,这里就像可乐的瓶子拧上雪碧的盖子,能拧的上却不美观.所以为了数据的精确性,PDA端也用百度地图的接口. 下面主要流程分为以下几步: 新建项目BaiduMapAPIDemo. 下载百度地图 --Android定位SDK . Binging Labrary项目添加相关文件. 注册百度开发平台,创建应用,获取AK. 写入百度提供示例代码. 查看输出结果. 第一步:新建项

第九篇:使用 lstat 函数获取文件信息

前言 在之前的文章中,描述过如何用 fcntl 函数改变文件的状态标记.但,文件还有很多信息,如文件类型,权限设置,设备编号,访问时间等等.如果要获取这些信息,则使用函数 lstat 可以轻松达到这个目的. 下面的程序将使用该函数获取文件类型信息并判断它的类型. 但在这之前,先要说明文件信息结构体和文件类型判定宏. 文件信息结构体 调用 lstat 函数将会把指定文件的信息存放到 stat 结构体中,这个结构体的定义大致如下: 文件类型判定宏 文件结构体中的文件类型字段是一个整数,对此,可以使用

Delphi Mercadopago支付【支持支持获取账户信息和余额、创建商店,商店查询、创建二维码、二维码查询、创建订单、订单查询、订单退款等功能】

Delphi Mercadopago支付下载 [Delphi Mercadopago支付]支持 支持支持获取账户信息和余额.创建商店,商店查询.创建二维码.二维码查询.创建订单.订单查询.订单退款等功能 原文地址:https://www.cnblogs.com/zhimamaigua/p/11251646.html

httpClient实现获取网络信息

自己实现的抓取网络信息 package util; import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.sql.Timestamp; import java.util.Date; import java.util.UUID; import org.apache.http.HttpEntity; import org.apache.http.Http

stat()函数--------------获取文件信息

stat():用于获取文件的状态信息,使用时需要包含<sys/stat.h>头文件. 函数原型:int stat(const char *path, struct stat *buf): struct stat { dev_t st_dev;         /* ID of device containing file */ ino_t st_ino;    /* inode number */ mode_t st_mode;  /* protection */ nlink_t st_nli

android通过查询电话号码获取联系人信息

[java] view plaincopyprint? // 取得Intent中的頭像 ivShowImage = (ImageView) findViewById(R.id.call_log_detail_contact_img); //通话电话号码获取头像uri Uri uriNumber2Contacts = Uri .parse("content://com.android.contacts/" + "data/phones/filter/" + strPh

Android Twitter第三方登录&amp;获取用户信息

Android接入Twitter先是去了Twitter的开发者网站,发现太麻烦,不太适用目前项目,转而接入了Twitter为java提供的twitter4j的jar包. 以下为接入Twitter4j的一些经验 官网地址:http://twitter4j.org/en/index.html#sourceCode 其中提供了jar包下载链接 Download 分为两个版本 ?Latest stable version (稳定版) ?Latest snapshot build (快照版) 快照版应该是

linux 获取本机MAC/IP地址的方法

功能:查询本机IP/MAC地址,过滤掉127.0.0.1 loop-back 地址 适用:linux, ubuntu 16.04 调试通过 #include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#includ