[FMX] 在Android/iOS 应用中判断上网的网络类型

因为2G网络实在是慢,所以在我们的App中,如果用户使用 2G 网络,App 的反应可能会比较缓慢,所以,我们希望判断一下网络的类型,以便做一些策略处理。

下面提供的函数是我根据搜索到的资料编写的一个函数,注意 Delphi 自带的 iOSApi.CoreTelephony 单元中,CTTelphonyNetworkInfo 缺少了一个函数,所以需要我们将其复制到我们工程目录下,加入该函数:

CTTelephonyNetworkInfo = interface(NSObject)
    ['{F75CE940-A78E-4C64-812E-0576386B582D}']
    function subscriberCellularProvider: CTCarrier; cdecl;
    procedure setSubscriberCellularProviderDidUpdateNotifier(Handler: TCellularProviderNotifier); cdecl;
    function currentRadioAccessTechnology:NSString;cdecl;//<--加入这一行
  end;

至于剩下的就好说了:

function GetNetType: TNetType;
{$IFDEF ANDROID}
  function AndroidNetType: TNetType;
  var
    AMgr: JConnectivityManager;
    ANetwork: JNetworkInfo;
    AType: Integer;
    ASubName: String;
  begin
    Result := TNetType.Other;
    AMgr := ConnectivityManager;
    if Assigned(AMgr) then
    begin
      ANetwork := AMgr.getActiveNetworkInfo;
      if Assigned(ANetwork) then
      begin
        AType := ANetwork.getType;
        if AType = TJConnectivityManager.JavaClass.TYPE_BLUETOOTH then
          Result := TNetType.Bluetooth
        else if AType = TJConnectivityManager.JavaClass.TYPE_ETHERNET then
          Result := TNetType.Ethernet
        else if AType = TJConnectivityManager.JavaClass.TYPE_WIFI then
          Result := TNetType.Wifi
        else if AType = TJConnectivityManager.JavaClass.TYPE_MOBILE then
        begin
          AType := TelephonyManager.getNetworkType;
          if (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_1xRTT) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_CDMA) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_EDGE) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_GPRS) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_IDEN) then
            Result := TNetType.Mobile2G
          else if (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_UMTS) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_EVDO_0) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_EVDO_A) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_EVDO_B) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_HSDPA) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_HSUPA) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_HSPA) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_EHRPD) or
            (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_HSPAP) then
            Result := TNetType.Mobile3G
          else if (AType = TJTelephonyManager.JavaClass.NETWORK_TYPE_LTE) then
            Result := TNetType.Mobile4G
          else
          begin
            ASubName := UpperCase(JStringToString(ANetwork.getSubtypeName));
            if (ASubName = 'TD-SCDMA') or (ASubName = 'WCDMA') or
              (ASubName = 'CDMA2000') then
              Result := TNetType.Mobile3G;
          end;
        end;
      end;
    end;
  end;

{$ENDIF}
{$IFDEF IOS}
  function iOSNetType: TNetType;
  var
    ANetInfo: CTTelephonyNetworkInfo;
    AName: String;
  begin
    if (ConnectionReachabilityFlags and kSCNetworkReachabilityFlagsIsWWAN) <> 0
    then
    begin
      ANetInfo := TCTTelephonyNetworkInfo.Create;
      AName := UpperCase(Copy(NSStrToStr(ANetInfo.currentRadioAccessTechnology),
        24, MaxInt));
      if (AName = 'GPRS') or (AName = 'EDGE') or (AName = 'CDMA1X') then
        Result := TNetType.Mobile2G
      else if (AName = 'WCDMA') or (AName = 'HSDPA') or (AName = 'HSUPA') or
        (AName = 'CDMAEVDOREV0') or (AName = 'CDMAEVDOREVA') or
        (AName = 'CDMAEVDOREVB') or (AName = 'HRPD') then
        Result := TNetType.Mobile3G
      else if (AName = 'LTE') then
        Result := TNetType.MobileLTE
      else
        Result := TNetType.Other;
    end
    else
      Result := TNetType.Wifi
  end;
{$ENDIF}

begin
  if IsInternetConnected then
  begin
{$IFDEF ANDROID}
    Result := AndroidNetType;
{$ENDIF}
{$IFDEF IOS}
    Result := iOSNetType;
{$ENDIF}
{$IFDEF MSWINDOWS}
    Result := TNetType.Other;
{$ENDIF}
  end
  else
    Result := TNetType.None;
end;

TNetType 是一个枚举类型,列出了连接到 Internet 的网络类型,自己 定义下。

另外,这个需要里面的一些函数,请参考以前的 [FMX] 在应用中检测是否已经联网 中的实现

分享到: