loadNetworkGeoInfo method
获取网络位置信息
Implementation
Future<NetworkGeoInfo?> loadNetworkGeoInfo() async {
// 如果已经有信息,直接返回
if (geoInfo != null) {
publicIP = geoInfo!.ip;
return geoInfo!;
}
// 定义多个服务商的 url 和解析方法
final List<_ProviderDefinition> providers = [
//开源免费
_ProviderDefinition(
url:
'http://ip-api.com/json/?lang=zh-CN&fields=status,message,country,countryCode,region,regionName,city,lat,lon,timezone,query,mobile',
parser: (data) {
try {
if (data is Map && data['status'] == 'success') {
return NetworkGeoInfo()
..ip = data['query'] ?? ''
..country = data['country'] ?? ''
..countryCode = data['countryCode'] ?? ''
..region = data['region'] ?? ''
..regionName = data['regionName'] ?? ''
..city = data['city'] ?? ''
..lat = (data['lat'] ?? 0.0).toDouble()
..lon = (data['lon'] ?? 0.0).toDouble()
..timezone = data['timezone'] ?? '';
}
return null;
} catch (_) {
return null;
}
},
),
// 免费:每分钟60次
_ProviderDefinition(
url: 'https://free.freeipapi.com/api/json/',
parser: (data) {
try {
if (data is Map) {
var timeZones = data['timeZones'] ?? [];
var timezone = timeZones.isNotEmpty ? timeZones.first : '';
return NetworkGeoInfo()
..ip = data['ipAddress'] ?? ''
..country = data['countryName'] ?? ''
..countryCode = data['countryCode'] ?? ''
..region = data['regionName'] ?? ''
..regionName = data['regionName'] ?? ''
..city = data['cityName'] ?? ''
..lat = (data['latitude'] ?? 0.0).toDouble()
..lon = (data['longitude'] ?? 0.0).toDouble()
..timezone = timezone;
}
return null;
} catch (_) {
return null;
}
},
),
//https://ipinfo.io/developers使用最新API,KEY方式无限制https://api.ipinfo.io/lite/me?token=2bbec5864d5271
_ProviderDefinition(
url: 'https://ipinfo.io/json',
parser: (data) {
try {
if (data is Map) {
return NetworkGeoInfo()
..ip = data['ip'] ?? ''
..country = data['country'] ?? ''
..countryCode = data['country'] ?? ''
..region = data['region'] ?? ''
..regionName = data['region'] ?? ''
..city = data['city'] ?? ''
..lat = 0.0
..lon = 0.0
..timezone = data['timezone'] ?? '';
}
} catch (_) {
return null;
}
return null;
},
),
// 免费
_ProviderDefinition(
url: 'https://ipv4-check-perf.radar.cloudflare.com/api/info',
parser: (data) {
try {
if (data is Map) {
return NetworkGeoInfo()
..ip = data['ip_address'] ?? ''
..country = data['country'] ?? ''
..countryCode = data['country'] ?? ''
..region = data['region'] ?? ''
..regionName = data['region'] ?? ''
..city = data['city'] ?? ''
..lat = 0.0
..lon = 0.0
..timezone = '';
}
} catch (_) {
return null;
}
return null;
},
),
// 每天免费30000次
_ProviderDefinition(
url: 'https://ipapi.co/json/',
parser: (data) {
try {
if (data is Map) {
return NetworkGeoInfo()
..ip = data['ip'] ?? ''
..country = data['country'] ?? ''
..countryCode = data['country_code'] ?? ''
..region = data['region'] ?? ''
..regionName = data['region_code'] ?? ''
..city = data['city'] ?? ''
..lat = 0.0
..lon = 0.0
..timezone = data['timezone'] ?? '';
}
} catch (_) {
return null;
}
return null;
},
),
//每天1500次
_ProviderDefinition(
url:
'https://api.ipdata.co?api-key=8d79f088ef95545378ef877ef2ecdff9ed4909d5e213e5a8a9a71b97&fields=ip,is_eu,city,region,region_code,country_name,country_code,continent_name,continent_code,latitude,longitude',
parser: (data) {
try {
if (data is Map) {
return NetworkGeoInfo()
..ip = data['ip'] ?? ''
..country = data['country_name'] ?? ''
..countryCode = data['country_code'] ?? ''
..region = data['region'] ?? ''
..regionName = data['region_code'] ?? ''
..city = data['city'] ?? ''
..lat = 0.0
..lon = 0.0
..timezone = data['timezone'] ?? '';
}
} catch (_) {
return null;
}
return null;
},
),
//每月30000次
_ProviderDefinition(
url:
'https://api.ipgeolocation.io/v2/ipgeo?apiKey=50c00e5864934ed7869d22ce078bcfb9',
parser: (data) {
try {
if (data is Map &&
data['ip'] != null &&
data['ip'].toString().isNotEmpty) {
var lat = 0.0;
var lon = 0.0;
if (data['location'] is Map) {
var locationMap = data['location'] as Map;
return NetworkGeoInfo()
..ip = data['ip'] ?? ''
..country = locationMap['country_name'] ?? ''
..countryCode = locationMap['country_code2'] ?? ''
..region = data['state_prov'] ?? ''
..regionName = data['state_code'] ?? ''
..city = data['city'] ?? ''
..lat = lat
..lon = lon
..timezone = data['timezone'] ?? '';
}
}
} catch (_) {
return null;
}
return null;
},
),
];
// 串行请求各服务商
for (final provider in providers) {
try {
final response = await Dio().get(provider.url);
final data = response.data;
final info = provider.parser(data);
if (info != null) {
publicIP = info.ip;
geoInfo = info;
break;
}
} catch (e) {
// ignore, 尝试下一个
Logger.log('IP定位服务失败: ${provider.url} 错误: $e');
}
}
return geoInfo;
}