开源鸿蒙跨平台Flutter开发:手机号码归属地查询应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图


1.1 应用简介
手机号码归属地查询是一款实用工具应用,为用户提供快速、准确的手机号码信息查询服务。支持查询手机号码归属地、运营商信息、号码段信息等,让用户轻松了解陌生号码来源。应用内置完整的号码段数据库,支持离线查询,响应速度快,数据准确可靠。
应用以蓝色为主色调,象征科技与信任。涵盖号码查询、历史记录、号码段查询、关于信息四大模块。用户可以输入手机号码查询详细信息,查看历史查询记录,了解号码段分布情况。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 号码查询 | 查询归属地和运营商 | 数据匹配 |
| 历史记录 | 保存查询历史 | 本地存储 |
| 号码段 | 查询号码段信息 | 列表展示 |
| 收藏夹 | 收藏重要号码 | 标记功能 |
| 号码验证 | 验证号码格式 | 正则匹配 |
1.3 运营商定义
| 序号 | 运营商名称 | Emoji | 号段范围 |
|---|---|---|---|
| 1 | 中国移动 | 📱 | 134-139, 147, 150-152, 157-159, 178, 182-184, 187-188, 198 |
| 2 | 中国联通 | 📞 | 130-132, 145, 155-156, 166, 175-176, 185-186, 196 |
| 3 中国电信 | ☎️ | 133, 149, 153, 173-174, 177, 180-181, 189, 191, 199 | |
| 4 | 虚拟运营商 | 📟 | 170, 171 |
1.4 号码段分布
| 序号 | 号段 | 运营商 | 归属地示例 |
|---|---|---|---|
| 1 | 138 | 中国移动 | 全国各地 |
| 2 | 139 | 中国移动 | 全国各地 |
| 3 | 186 | 中国联通 | 全国各地 |
| 4 | 189 | 中国电信 | 全国各地 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 数据存储 | 内存存储 | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.6 项目结构
lib/
└── main_phone_location.dart
├── PhoneLocationApp # 应用入口
├── Carrier # 运营商枚举
├── PhoneLocation # 号码归属地模型
├── PhoneSegment # 号码段模型
├── QueryRecord # 查询记录模型
├── PhoneLocationHomePage # 主页面(底部导航)
├── _buildQueryPage # 查询页面
├── _buildHistoryPage # 历史页面
├── _buildSegmentsPage # 号码段页面
├── _buildAboutPage # 关于页面
├── PhoneLocationService # 查询服务
├── PhoneInputField # 输入框组件
└── LocationCard # 结果卡片组件
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 查询处理流程
三、核心模块设计
3.1 数据模型设计
3.1.1 运营商枚举 (Carrier)
enum Carrier {
mobile(
label: '中国移动',
emoji: '📱',
prefixes: ['134', '135', '136', '137', '138', '139', '147', '150', '151', '152', '157', '158', '159', '178', '182', '183', '184', '187', '188', '198'],
),
unicom(
label: '中国联通',
emoji: '📞',
prefixes: ['130', '131', '132', '145', '155', '156', '166', '175', '176', '185', '186', '196'],
),
telecom(
label: '中国电信',
emoji: '☎️',
prefixes: ['133', '149', '153', '173', '174', '177', '180', '181', '189', '191', '199'],
),
virtual(
label: '虚拟运营商',
emoji: '📟',
prefixes: ['170', '171'],
);
final String label;
final String emoji;
final List<String> prefixes;
}
3.1.2 号码归属地模型 (PhoneLocation)
class PhoneLocation {
final String phoneNumber; // 手机号码
final String province; // 省份
final String city; // 城市
final Carrier carrier; // 运营商
final String areaCode; // 区号
final String zipCode; // 邮编
final String segment; // 号码段
final bool isValid; // 是否有效
}
3.1.3 号码段模型 (PhoneSegment)
class PhoneSegment {
final String prefix; // 号段前缀
final Carrier carrier; // 运营商
final String description; // 描述
final int totalCount; // 号码总数
}
3.1.4 查询记录模型 (QueryRecord)
class QueryRecord {
final String id; // 记录ID
final String phoneNumber; // 手机号码
final PhoneLocation location; // 归属地信息
final DateTime queryTime; // 查询时间
final bool isFavorite; // 是否收藏
}
3.1.5 运营商分布
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 查询页结构
3.2.3 历史页结构
3.2.4 号码段页结构
3.3 号码验证逻辑
3.4 归属地查询逻辑
四、UI设计规范
4.1 配色方案
应用以蓝色为主色调,象征科技与信任:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #2196F3 (Blue) | 导航、主题元素 |
| 辅助色 | #42A5F5 | 查询页面 |
| 第三色 | #64B5F6 | 历史页面 |
| 强调色 | #90CAF9 | 号码段页面 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 结果卡片 |
4.2 运营商颜色
| 运营商 | 色值 | 视觉效果 |
|---|---|---|
| 中国移动 | #00A0E9 | 科技蓝 |
| 中国联通 | #FF6600 | 活力橙 |
| 中国电信 | #0085D0 | 稳重蓝 |
| 虚拟运营商 | #9C27B0 | 神秘紫 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 号码显示 | 28px | Bold | #000000 |
| 归属地 | 18px | Regular | #333333 |
| 运营商 | 16px | Medium | 运营商色 |
| 提示文字 | 12px | Regular | #999999 |
4.4 组件规范
4.4.1 号码输入框
┌─────────────────────────────────────┐
│ 输入手机号码 │
│ │
│ ┌─────────────────────────────┐ │
│ │ 138 0013 8000 ✕ │ │
│ └─────────────────────────────┘ │
│ │
│ 请输入11位手机号码 │
└─────────────────────────────────────┘
4.4.2 查询结果卡片
┌─────────────────────────────────────┐
│ 查询结果 │
│ │
│ ┌─────────────────────────────┐ │
│ │ 138 0013 8000 │ │
│ │ │ │
│ │ 📍 北京市 北京 │ │
│ │ 📱 中国移动 │ │
│ │ 🔢 号段: 138 │ │
│ │ ☎️ 区号: 010 │ │
│ │ 📮 邮编: 100000 │ │
│ │ │ │
│ │ [收藏] [分享] [复制] │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
4.4.3 历史记录卡片
┌─────────────────────────────────────┐
│ 查询历史 │
│ │
│ 📅 今天 │
│ ┌─────────────────────────────┐ │
│ │ 138****8000 │ │
│ │ 北京市 北京 | 中国移动 │ │
│ │ 10:30 │ │
│ └─────────────────────────────┘ │
│ │
│ 📅 昨天 │
│ ┌─────────────────────────────┐ │
│ │ 186****1234 │ │
│ │ 上海市 上海 | 中国联通 │ │
│ │ 15:20 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
4.4.4 号码段列表
┌─────────────────────────────────────┐
│ 号码段信息 │
│ │
│ [全部] [移动] [联通] [电信] │
│ │
│ ┌─────────────────────────────┐ │
│ │ 📱 138号段 │ │
│ │ 中国移动 | 约1000万个号码 │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ 📞 186号段 │ │
│ │ 中国联通 | 约800万个号码 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
4.4.5 运营商筛选
┌─────────────────────────────────────┐
│ 选择运营商 │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 📱 │ │ 📞 │ │ ☎️ │ │
│ │ 移动 │ │ 联通 │ │ 电信 │ │
│ └──────┘ └──────┘ └──────┘ │
│ ┌──────┐ │
│ │ 📟 │ │
│ │ 虚拟 │ │
│ └──────┘ │
└─────────────────────────────────────┘
五、核心功能实现
5.1 号码验证实现
class PhoneValidator {
static bool validate(String phone) {
// 验证长度
if (phone.length != 11) {
return false;
}
// 验证是否全为数字
if (!RegExp(r'^\d{11}$').hasMatch(phone)) {
return false;
}
// 验证号段
final prefix = phone.substring(0, 3);
return Carrier.values.any((carrier) =>
carrier.prefixes.contains(prefix)
);
}
static String? validateWithMessage(String phone) {
if (phone.length != 11) {
return '请输入11位手机号码';
}
if (!RegExp(r'^\d{11}$').hasMatch(phone)) {
return '手机号码只能包含数字';
}
final prefix = phone.substring(0, 3);
final isValidPrefix = Carrier.values.any((carrier) =>
carrier.prefixes.contains(prefix)
);
if (!isValidPrefix) {
return '无效的手机号码段';
}
return null;
}
}
5.2 归属地查询实现
class PhoneLocationService {
static final Map<String, Map<String, String>> _locationData = {
'1380013': {'province': '北京', 'city': '北京', 'areaCode': '010', 'zipCode': '100000'},
'1380014': {'province': '上海', 'city': '上海', 'areaCode': '021', 'zipCode': '200000'},
'1860001': {'province': '广东', 'city': '广州', 'areaCode': '020', 'zipCode': '510000'},
// ... 更多号码段数据
};
static PhoneLocation query(String phone) {
if (!PhoneValidator.validate(phone)) {
return PhoneLocation(
phoneNumber: phone,
isValid: false,
);
}
final prefix = phone.substring(0, 3);
final segment = phone.substring(0, 7);
final carrier = _getCarrier(prefix);
final location = _locationData[segment] ?? {
'province': '未知',
'city': '未知',
'areaCode': '',
'zipCode': '',
};
return PhoneLocation(
phoneNumber: phone,
province: location['province']!,
city: location['city']!,
carrier: carrier,
areaCode: location['areaCode']!,
zipCode: location['zipCode']!,
segment: prefix,
isValid: true,
);
}
static Carrier _getCarrier(String prefix) {
return Carrier.values.firstWhere(
(carrier) => carrier.prefixes.contains(prefix),
orElse: () => Carrier.mobile,
);
}
}
5.3 号码格式化实现
class PhoneFormatter {
static String format(String phone) {
if (phone.length != 11) {
return phone;
}
return '${phone.substring(0, 3)} ${phone.substring(3, 7)} ${phone.substring(7)}';
}
static String mask(String phone) {
if (phone.length != 11) {
return phone;
}
return '${phone.substring(0, 3)}****${phone.substring(7)}';
}
static String clean(String phone) {
return phone.replaceAll(RegExp(r'\D'), '');
}
}
5.4 历史记录管理实现
class QueryHistoryManager {
static final List<QueryRecord> _records = [];
static void add(QueryRecord record) {
// 检查是否已存在
final existingIndex = _records.indexWhere((r) => r.phoneNumber == record.phoneNumber);
if (existingIndex >= 0) {
// 更新查询时间
_records.removeAt(existingIndex);
}
// 添加到列表开头
_records.insert(0, record);
// 限制历史记录数量
if (_records.length > 100) {
_records.removeLast();
}
}
static List<QueryRecord> getAll() {
return List.from(_records);
}
static List<QueryRecord> getByDate(DateTime date) {
return _records.where((record) =>
record.queryTime.year == date.year &&
record.queryTime.month == date.month &&
record.queryTime.day == date.day
).toList();
}
static void clear() {
_records.clear();
}
static void toggleFavorite(String id) {
final index = _records.indexWhere((r) => r.id == id);
if (index >= 0) {
final record = _records[index];
_records[index] = QueryRecord(
id: record.id,
phoneNumber: record.phoneNumber,
location: record.location,
queryTime: record.queryTime,
isFavorite: !record.isFavorite,
);
}
}
}
5.5 号码段查询实现
class PhoneSegmentService {
static List<PhoneSegment> getAllSegments() {
final segments = <PhoneSegment>[];
for (var carrier in Carrier.values) {
for (var prefix in carrier.prefixes) {
segments.add(PhoneSegment(
prefix: prefix,
carrier: carrier,
description: '${carrier.label}$prefix号段',
totalCount: 10000000, // 每个号段约1000万个号码
));
}
}
return segments;
}
static List<PhoneSegment> getSegmentsByCarrier(Carrier carrier) {
return getAllSegments().where((segment) => segment.carrier == carrier).toList();
}
static PhoneSegment? getSegment(String prefix) {
final segments = getAllSegments();
return segments.firstWhereOrNull((segment) => segment.prefix == prefix);
}
}
六、交互设计
6.1 查询流程
6.2 历史记录流程
6.3 号码段浏览流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 API接口集成
API功能:
- 实时号码信息查询
- 号码归属地更新
- 号码状态检测
- 号码标记查询
7.2.2 批量查询功能
批量功能:
- 批量号码导入
- 批量查询处理
- 结果导出Excel
- 统计分析报告
7.2.3 号码标记功能
标记功能:
- 骚扰电话标记
- 诈骗电话预警
- 推销电话识别
- 用户标记共享
八、注意事项
8.1 开发注意事项
-
数据准确性:号码段数据需定期更新
-
隐私保护:历史记录需脱敏处理
-
性能优化:大量历史记录需优化加载
-
用户体验:输入框需支持快捷操作
-
错误处理:无效号码需友好提示
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 查询结果不准 | 号段数据过时 | 更新数据库 |
| 历史记录丢失 | 未持久化 | 实现数据存储 |
| 号码验证错误 | 正则表达式错 | 修正验证规则 |
| 运营商识别错 | 号段未更新 | 添加新号段 |
| 查询速度慢 | 数据库未优化 | 优化索引 |
8.3 使用技巧
📱 号码查询技巧 📱
号码输入
- 支持11位手机号码查询
- 自动过滤非数字字符
- 支持粘贴快捷输入
- 实时格式验证
查询结果
- 显示完整归属地信息
- 提供运营商详细信息
- 包含区号邮编参考
- 支持一键复制分享
历史管理
- 自动保存查询记录
- 支持收藏重要号码
- 按日期分组显示
- 支持批量删除
号码段信息
- 查看各运营商号段
- 了解号码分布情况
- 支持运营商筛选
- 快速定位号段
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
| Web浏览器 | Chrome 90+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_phone_location.dart --web-port 8141
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_phone_location.dart
# 代码分析
flutter analyze lib/main_phone_location.dart
十、总结
手机号码归属地查询应用是一款实用工具应用,通过号码查询、历史记录、号码段查询、关于信息四大模块,为用户提供快速、准确的手机号码信息查询服务。应用支持查询手机号码归属地、运营商信息、号码段信息等,让用户轻松了解陌生号码来源。
核心功能涵盖号码查询、历史管理、号码段浏览、号码验证四大模块。号码查询支持11位手机号码查询,显示归属地、运营商、区号邮编等信息;历史管理自动保存查询记录,支持收藏和删除操作;号码段浏览展示各运营商号段分布,支持筛选和搜索;号码验证实时验证号码格式,提供友好的错误提示。
应用采用 Material Design 3 设计规范,以蓝色为主色调,象征科技与信任。通过本应用,希望能够帮助用户快速查询手机号码信息,识别陌生号码来源,提供便捷的号码管理服务。
手机号码归属地查询——快速准确,值得信赖
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)