Flutter for OpenHarmony:dart_ipify 一行代码获取公网 IP 地址,不再自己维护接口(IP 查询服务) 深度解析与鸿蒙适配指南
本文介绍了使用dart_ipify库查询公网IP和地理位置的方法。该库封装了ipify.org的API,支持免费查询IPv4/IPv6地址,并可通过API Key获取ISP和地理位置信息。文章详细讲解了基础用法、地理位置查询、常见应用场景(如自动切换服务器区域、安全风控和调试工具)以及OpenHarmony平台适配注意事项。最后提供了一个完整的Flutter示例代码,展示如何构建一个IP查询应用,
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言
在做 P2P 应用、日志记录或地域限制功能时,经常需要知道用户的真实公网 IP。虽然可以自己写个后端 API 返回 request.ip,或者爬取 icanhazip.com,但这些方法要么麻烦,要么不稳定。
dart_ipify 封装了著名的 ipify.org 公共 API,它不仅提供 IPv4/IPv6 查询,还能返回 ISP(运营商)和地理位置信息(需 API Key)。最重要的是,它极其简单稳定,永久免费(基础查询)。
一、概念介绍/原理解析
1.1 基础概念
- Public IP: 路由器在互联网上的唯一出口地址(区别于 192.168.x.x 内网 IP)。
- Geolocation: 根据 IP 反查地理位置(国家、城市、经纬度)。
- Ipify: 一个高性能的 IP 地址 API 服务,基于 AWS Lambda 构建,无请求限制。
1.2 进阶概念
它支持 HTTPS 加密传输,确保 IP 信息不被中间人篡改。同时也提供了对 geo-ipify 的支持,适合需要精确位置的场景。
二、核心 API/组件详解
2.1 依赖安装
dependencies:
dart_ipify: ^1.0.0
2.2 基础用法
获取纯文本 IP 地址(免费,无 Key)。
import 'package:dart_ipify/dart_ipify.dart';
void main() async {
// 1.IPv4
final ipv4 = await Ipify.ipv4();
print(ipv4); // "98.207.254.136"
// 2. IPv6 (如果网络支持)
// final ipv6 = await Ipify.ipv64();
}
2.3 地理位置查询
需 注册 获取 API Key。
final geo = await Ipify.geo('YOUR_API_KEY');
print(geo.location.city); // "Mountain View"
print(geo.isp); // "Google LLC"

三、常见应用场景
3.1 场景 1:自动切换服务器区域
根据用户 IP 所在的国家(如 US, CN),自动选择最近的 CDN 节点或游戏服务器。
final location = await Ipify.geo(key);
if (location.location.country == 'CN') {
Config.setBaseUrl('https://cn.api.com');
} else {
Config.setBaseUrl('https://us.api.com');
}

3.2 场景 2:安全风控
检测用户是否频繁更换 IP,或者处于异常地理位置(如账号常在上海,突然在尼日利亚登录)。
if (lastIp != currentIp && distance(lastLoc, currentLoc) > 1000km) {
triggerSecurityCheck();
}

3.3 场景 3:调试工具
在 App 的“关于”或“调试模式”页面,显示当前网络出口 IP,方便测试人员排查问题。
ListTile(
title: Text('Public IP'),
subtitle: FutureBuilder(
future: Ipify.ipv4(),
builder: (ctx, snap) => Text(snap.data ?? 'Loading...'),
),
);

四、OpenHarmony 平台适配
4.1 网络权限
查询 IP 需要访问互联网,务必在 config.json / module.json5 中声明 ohos.permission.INTERNET。
4.2 稳定性
Ipify 服务在海外,国内访问速度偶尔波动。建议在 OpenHarmony 侧做一层超时处理(Timeout)或增加重试机制,避免阻塞主流程。
五、完整示例代码
本示例展示在鸿蒙设备上查询本机公网 IP 及地理位置信息。
import 'package:flutter/material.dart';
import 'package:dart_ipify/dart_ipify.dart';
void main() {
runApp(const MaterialApp(home: IpPage()));
}
class IpPage extends StatefulWidget {
const IpPage({super.key});
State<IpPage> createState() => _IpPageState();
}
class _IpPageState extends State<IpPage> {
String _ip = '';
String _location = '';
bool _loading = false;
Future<void> _fetchIp() async {
setState(() {
_loading = true;
_ip = '';
_location = '';
});
try {
// 1. 获取 IP (免费)
final ip = await Ipify.ipv4();
_ip = ip;
// 2. 获取地理位置 (需要 Key,这里演示用)
// 如果没有 Key,可以跳过此步骤
// final geo = await Ipify.geo('YOUR_API_KEY');
// _location = '${geo.location.city}, ${geo.location.country}';
_location = '需要 API Key 才能显示详细位置';
} catch (e) {
_ip = '查询失败';
print(e);
} finally {
if (mounted) setState(() => _loading = false);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('我的 IP 地址')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_loading) const CircularProgressIndicator(),
if (!_loading) ...[
const Text('Public IPv4', style: TextStyle(color: Colors.grey)),
Text(
_ip.isEmpty ? '点击按钮查询' : _ip,
style: const TextStyle(fontSize: 32, fontWeight: FontWeight.bold, color: Colors.blue),
),
const SizedBox(height: 10),
const Text('Location', style: TextStyle(color: Colors.grey)),
Text(_location, style: const TextStyle(fontSize: 16)),
],
const SizedBox(height: 40),
ElevatedButton.icon(
onPressed: _fetchIp,
icon: const Icon(Icons.refresh),
label: const Text('查询'),
),
],
),
),
);
}
}
六、总结
dart_ipify 解决了“我是谁,我在哪”的问题。虽然功能单一,但在特定场景下(如检测代理、区域限制)极其好用。
最佳实践:
- 缓存:IP 地址通常不会频繁变动(除非重启路由器或切换网络),获取一次后应缓存在内存或本地,避免每次打开 App 都请求。
- Privacy:注意隐私合规,未经用户同意,不要滥用位置信息用于追踪。
更多推荐

所有评论(0)