在这里插入图片描述

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

🎯 欢迎来到 Flutter for OpenHarmony 第三方库实战系列!本文将带你实现设备信息获取功能,通过 device_info_plus 库获取设备的型号、系统版本、品牌等硬件和系统信息。


🚀 项目概述:我们要构建什么?

在应用开发中,获取设备信息是常见需求,例如统计分析用户设备分布、针对不同设备优化体验、崩溃日志记录设备信息、设备绑定功能等。device_info_plus 提供了跨平台的设备信息获取能力,支持获取设备型号、系统版本、品牌、制造商等详细信息。

本文将构建的应用具备以下核心特性:

📱 设备标识:获取设备型号、品牌、制造商等标识信息。

💻 系统信息:获取操作系统名称、版本等系统信息。

🔧 硬件信息:获取 CPU 架构、内存等硬件信息。

📊 信息展示:完整的设备信息展示界面。

OpenHarmony

Android

iOS

复制信息

刷新

应用启动

获取 DeviceInfoPlugin 实例

判断平台

获取 OpenHarmonyDeviceInfo

获取 AndroidDeviceInfo

获取 IosDeviceInfo

品牌/型号/系统版本

品牌/型号/SDK版本

型号/系统版本/标识符

展示设备信息

用户操作

复制到剪贴板

重新获取

🎯 核心功能一览

功能模块 属性 核心能力
📱 设备标识 model, brand, manufacturer 获取设备型号、品牌、制造商
💻 系统信息 systemName, systemVersion 获取系统名称和版本
🔧 硬件信息 supportedCpuArchitectures 获取 CPU 架构信息
🆔 设备唯一标识 deviceId 获取设备唯一标识符

💡 为什么选择 device_info_plus?

1️⃣ 官方维护

Flutter Community 官方维护的插件,质量和更新有保障。

2️⃣ 跨平台支持

支持 Android、iOS、macOS、Windows、Linux、Web 和 OpenHarmony 等多个平台。

3️⃣ 平台适配

不同平台返回特定的设备信息类,包含该平台特有的属性。

4️⃣ OpenHarmony 原生适配

专门针对 OpenHarmony 平台进行了适配,提供完整的设备信息。

📋 各平台可获取的信息

属性 OpenHarmony Android iOS
品牌 (brand) ✅ (Apple)
型号 (model)
制造商 (manufacture) ✅ (Apple)
系统版本
SDK 版本
设备类型

📦 第一步:环境配置

1.1 添加依赖

在开始编码之前,我们需要先配置项目的依赖。打开项目根目录下的 pubspec.yaml 文件,添加以下内容。

dependencies:
  flutter:
    sdk: flutter

  # 设备信息获取(OpenHarmony 适配版本)
  device_info_plus:
    git:
      url: "https://atomgit.com/openharmony-sig/flutter_plus_plugins.git"
      path: "packages/device_info_plus/device_info_plus"

1.2 执行依赖安装

配置完成后,在项目根目录执行以下命令来下载并安装所有依赖包。

flutter pub get

📱 第二步:设备信息获取详解

2.1 核心 API 介绍

DeviceInfoPlugin 类

主接口类,提供设备信息获取功能。

class DeviceInfoPlugin {
  // 获取 OpenHarmony 设备信息
  Future<OhosDeviceInfo> ohosInfo;
  
  // 获取 Android 设备信息
  Future<AndroidDeviceInfo> androidInfo;
  
  // 获取 iOS 设备信息
  Future<IosDeviceInfo> iosInfo;
  
  // 获取通用设备信息(根据平台自动选择)
  Future<BaseDeviceInfo> deviceInfo;
}

OhosDeviceInfo 类

OpenHarmony 平台特有的设备信息类。

class OhosDeviceInfo extends BaseDeviceInfo {
  // 设备类型(phone, tablet, wearable 等)
  final String deviceType;
  
  // 设备品牌
  final String brand;
  
  // 制造商
  final String manufacture;
  
  // 市场名称
  final String marketName;
  
  // 产品系列
  final String productSeries;
  
  // 产品型号
  final String productModel;
  
  // 软件型号
  final String softwareModel;
  
  // 硬件型号
  final String hardwareModel;
  
  // 系统全名
  final String osFullName;
  
  // SDK 版本
  final int sdkApiVersion;
  
  // 显示版本
  final String displayVersion;
  
  // 增量版本
  final String incrementalVersion;
  
  // 安全补丁
  final String securityPatchTag;
  
  // CPU 架构列表
  final String abiList;
  
  // ODID(OpenHarmony Device ID)
  final String odID;
}

⚠️ 重要说明

  • 不同平台返回不同的设备信息类
  • 某些属性在某些设备上可能返回空值
  • 设备 ID 不保证在应用重装后保持不变

2.2 设备信息获取服务实现

下面的 DeviceInfoService 类封装了设备信息获取的逻辑。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:device_info_plus/device_info_plus.dart';

class DeviceInfoService extends ChangeNotifier {
  final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
  
  BaseDeviceInfo? _deviceData;
  bool _isLoaded = false;
  String? _errorMessage;
  String _platform = '';

  BaseDeviceInfo? get deviceData => _deviceData;
  bool get isLoaded => _isLoaded;
  String? get errorMessage => _errorMessage;
  String get platform => _platform;

  Future<void> load() async {
    try {
      if (Platform.isAndroid) {
        _platform = 'Android';
        _deviceData = await _deviceInfo.androidInfo;
      } else if (Platform.isIOS) {
        _platform = 'iOS';
        _deviceData = await _deviceInfo.iosInfo;
      } else {
        _platform = 'OpenHarmony';
        _deviceData = await _deviceInfo.ohosInfo;
      }
    
      _isLoaded = true;
      notifyListeners();
    } catch (e) {
      _errorMessage = '获取设备信息失败: $e';
      notifyListeners();
    }
  }

  Map<String, dynamic> toMap() {
    if (_deviceData == null) return {};
  
    if (_deviceData is OhosDeviceInfo) {
      final info = _deviceData as OhosDeviceInfo;
      return {
        '设备类型': info.deviceType,
        '品牌': info.brand,
        '制造商': info.manufacture,
        '市场名称': info.marketName,
        '产品型号': info.productModel,
        '系统全名': info.osFullName,
        'SDK版本': info.sdkApiVersion.toString(),
        '显示版本': info.displayVersion,
        '安全补丁': info.securityPatchTag,
        'CPU架构': info.abiList,
      };
    } else if (_deviceData is AndroidDeviceInfo) {
      final info = _deviceData as AndroidDeviceInfo;
      return {
        '品牌': info.brand,
        '型号': info.model,
        '制造商': info.manufacturer,
        'Android版本': info.version.release,
        'SDK版本': info.version.sdkInt.toString(),
        '设备ID': info.id,
        'CPU架构': info.supportedAbis.join(', '),
      };
    } else if (_deviceData is IosDeviceInfo) {
      final info = _deviceData as IosDeviceInfo;
      return {
        '型号': info.model,
        '系统名称': info.systemName,
        '系统版本': info.systemVersion,
        '设备名称': info.name,
        '标识符': info.identifierForVendor ?? '未知',
      };
    }
  
    return {};
  }
}

🎨 第三步:完整示例代码

下面是一个完整的设备信息展示应用。

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:device_info_plus/device_info_plus.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Device Info Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
        useMaterial3: true,
      ),
      home: const DeviceInfoPage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class DeviceInfoPage extends StatefulWidget {
  const DeviceInfoPage({super.key});

  
  State<DeviceInfoPage> createState() => _DeviceInfoPageState();
}

class _DeviceInfoPageState extends State<DeviceInfoPage> {
  final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
  Map<String, dynamic> _deviceData = {};
  bool _isLoading = true;
  String _platform = '';

  
  void initState() {
    super.initState();
    _loadDeviceInfo();
  }

  Future<void> _loadDeviceInfo() async {
    Map<String, dynamic> data = {};
    String platform = '';

    try {
      if (Platform.isAndroid) {
        platform = 'Android';
        final info = await _deviceInfo.androidInfo;
        data = _readAndroidInfo(info);
      } else if (Platform.isIOS) {
        platform = 'iOS';
        final info = await _deviceInfo.iosInfo;
        data = _readIosInfo(info);
      } else {
        platform = 'OpenHarmony';
        final info = await _deviceInfo.ohosInfo;
        data = _readOhosInfo(info);
      }
    } catch (e) {
      data = {'错误': e.toString()};
    }

    setState(() {
      _deviceData = data;
      _platform = platform;
      _isLoading = false;
    });
  }

  Map<String, dynamic> _readOhosInfo(OhosDeviceInfo info) {
    return {
      '设备类型': info.deviceType,
      '品牌': info.brand,
      '制造商': info.manufacture,
      '市场名称': info.marketName,
      '产品型号': info.productModel,
      '系统全名': info.osFullName,
      'SDK版本': info.sdkApiVersion.toString(),
      '显示版本': info.displayVersion,
      '增量版本': info.incrementalVersion,
      '安全补丁': info.securityPatchTag,
      'CPU架构': info.abiList,
    };
  }

  Map<String, dynamic> _readAndroidInfo(AndroidDeviceInfo info) {
    return {
      '品牌': info.brand,
      '型号': info.model,
      '制造商': info.manufacturer,
      '设备名称': info.device,
      'Android版本': info.version.release,
      'SDK版本': info.version.sdkInt.toString(),
      '安全补丁': info.version.securityPatch ?? '未知',
      '设备ID': info.id,
      'CPU架构': info.supportedAbis.join(', '),
      '是否模拟器': info.isPhysicalDevice ? '否' : '是',
    };
  }

  Map<String, dynamic> _readIosInfo(IosDeviceInfo info) {
    return {
      '型号': info.model,
      '设备名称': info.name,
      '系统名称': info.systemName,
      '系统版本': info.systemVersion,
      '标识符': info.identifierForVendor ?? '未知',
      '是否模拟器': info.isPhysicalDevice ? '否' : '是',
    };
  }

  void _copyToClipboard(String text, String label) {
    Clipboard.setData(ClipboardData(text: text));
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('$label 已复制到剪贴板')),
    );
  }

  void _copyAllInfo() {
    final buffer = StringBuffer();
    buffer.writeln('平台: $_platform');
    _deviceData.forEach((key, value) {
      buffer.writeln('$key: $value');
    });
  
    Clipboard.setData(ClipboardData(text: buffer.toString()));
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('所有信息已复制到剪贴板')),
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('设备信息'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        actions: [
          IconButton(
            icon: const Icon(Icons.copy),
            onPressed: _deviceData.isNotEmpty ? _copyAllInfo : null,
            tooltip: '复制全部信息',
          ),
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () {
              setState(() => _isLoading = true);
              _loadDeviceInfo();
            },
            tooltip: '刷新',
          ),
        ],
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : _buildContent(),
    );
  }

  Widget _buildContent() {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: Column(
        children: [
          _buildPlatformHeader(),
          const SizedBox(height: 16),
          _buildDeviceInfoCard(),
          const SizedBox(height: 16),
          _buildUsageTips(),
        ],
      ),
    );
  }

  Widget _buildPlatformHeader() {
    IconData platformIcon;
    Color platformColor;

    switch (_platform) {
      case 'Android':
        platformIcon = Icons.android;
        platformColor = Colors.green;
        break;
      case 'iOS':
        platformIcon = Icons.phone_iphone;
        platformColor = Colors.blue;
        break;
      case 'OpenHarmony':
        platformIcon = Icons.devices;
        platformColor = Colors.teal;
        break;
      default:
        platformIcon = Icons.device_unknown;
        platformColor = Colors.grey;
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          children: [
            Container(
              width: 80,
              height: 80,
              decoration: BoxDecoration(
                color: platformColor.withOpacity(0.1),
                borderRadius: BorderRadius.circular(16),
              ),
              child: Icon(
                platformIcon,
                size: 48,
                color: platformColor,
              ),
            ),
            const SizedBox(height: 16),
            Text(
              _platform,
              style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 4),
            Text(
              '设备信息详情',
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: Colors.grey,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildDeviceInfoCard() {
    return Card(
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: Row(
              children: [
                Icon(
                  Icons.info_outline,
                  color: Theme.of(context).colorScheme.primary,
                ),
                const SizedBox(width: 8),
                Text(
                  '设备详情',
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
          const Divider(height: 1),
          ..._deviceData.entries.map((entry) => _buildInfoTile(
            entry.key,
            entry.value.toString(),
          )),
        ],
      ),
    );
  }

  Widget _buildInfoTile(String label, String value) {
    return ListTile(
      title: Text(
        label,
        style: TextStyle(
          color: Colors.grey.shade600,
          fontSize: 14,
        ),
      ),
      subtitle: Text(
        value,
        style: const TextStyle(
          fontFamily: 'monospace',
          fontSize: 15,
          color: Colors.black87,
        ),
      ),
      trailing: IconButton(
        icon: const Icon(Icons.copy, size: 20),
        onPressed: () => _copyToClipboard(value, label),
        tooltip: '复制',
      ),
    );
  }

  Widget _buildUsageTips() {
    return Card(
      color: Theme.of(context).colorScheme.surfaceContainerHighest,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(
                  Icons.lightbulb_outline,
                  color: Theme.of(context).colorScheme.primary,
                ),
                const SizedBox(width: 8),
                Text(
                  '使用场景',
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 12),
            const Text('• 统计分析用户设备分布'),
            const Text('• 针对不同设备优化体验'),
            const Text('• 崩溃日志记录设备信息'),
            const Text('• 设备绑定功能实现'),
            const Text('• 区分真机和模拟器'),
          ],
        ),
      ),
    );
  }
}

❓ 第四步:常见问题与解决方案

1. 设备 ID 在应用重装后变化

原因:设备 ID 不是硬件唯一标识,应用重装后会重新生成。

解决方案

// 如果需要持久化的设备标识,可以结合存储使用
class DeviceIdentifier {
  static const _key = 'device_identifier';
  
  static Future<String> getPersistentId() async {
    final prefs = await SharedPreferences.getInstance();
  
    var id = prefs.getString(_key);
    if (id == null) {
      id = const Uuid().v4();
      await prefs.setString(_key, id);
    }
  
    return id;
  }
}

2. 某些设备信息返回空值

原因:不同设备、不同系统版本支持的属性不同。

解决方案

String getSafeValue(String? value, [String defaultValue = '未知']) {
  if (value == null || value.isEmpty) {
    return defaultValue;
  }
  return value;
}

// 使用
Text('品牌: ${getSafeValue(info.brand)}')

3. 区分真机和模拟器

解决方案

Future<bool> isPhysicalDevice() async {
  final deviceInfo = DeviceInfoPlugin();
  
  if (Platform.isAndroid) {
    final info = await deviceInfo.androidInfo;
    return info.isPhysicalDevice;
  } else if (Platform.isIOS) {
    final info = await deviceInfo.iosInfo;
    return info.isPhysicalDevice;
  }
  
  // OpenHarmony 默认返回 true
  return true;
}

4. 获取设备类型(手机/平板)

解决方案

String getDeviceType() {
  final data = MediaQuery.of(context);
  final shortestSide = data.size.shortestSide;
  
  if (shortestSide < 600) {
    return '手机';
  } else if (shortestSide < 900) {
    return '平板';
  } else {
    return '大屏设备';
  }
}

5. 判断是否为特定品牌设备

解决方案

class DeviceBrandChecker {
  static Future<bool> isHuawei() async {
    final deviceInfo = DeviceInfoPlugin();
  
    if (Platform.isAndroid) {
      final info = await deviceInfo.androidInfo;
      return info.brand.toLowerCase() == 'huawei' ||
             info.brand.toLowerCase() == 'honor';
    }
  
    return false;
  }
  
  static Future<bool> isXiaomi() async {
    final deviceInfo = DeviceInfoPlugin();
  
    if (Platform.isAndroid) {
      final info = await deviceInfo.androidInfo;
      return info.brand.toLowerCase() == 'xiaomi' ||
             info.brand.toLowerCase() == 'redmi';
    }
  
    return false;
  }
}

6. 获取完整的设备描述

解决方案

Future<String> getDeviceDescription() async {
  final deviceInfo = DeviceInfoPlugin();
  
  if (Platform.isAndroid) {
    final info = await deviceInfo.androidInfo;
    return '${info.brand} ${info.model} (Android ${info.version.release})';
  } else if (Platform.isIOS) {
    final info = await deviceInfo.iosInfo;
    return '${info.model} (${info.systemName} ${info.systemVersion})';
  } else {
    final info = await deviceInfo.ohosInfo;
    return '${info.brand} ${info.productModel} (OpenHarmony ${info.osFullName})';
  }
}


📚 API 参考

DeviceInfoPlugin 类

方法 参数 返回值 说明
ohosInfo Future<OhosDeviceInfo> 获取 OpenHarmony 信息
androidInfo Future<AndroidDeviceInfo> 获取 Android 信息
iosInfo Future<IosDeviceInfo> 获取 iOS 信息
deviceInfo Future<BaseDeviceInfo> 获取通用设备信息

OhosDeviceInfo 属性

属性 类型 说明
deviceType String 设备类型
brand String 设备品牌
manufacture String 制造商
marketName String 市场名称
productModel String 产品型号
osFullName String 系统全名
sdkApiVersion int SDK 版本
displayVersion String 显示版本
incrementalVersion String 增量版本
securityPatchTag String 安全补丁
abiList String CPU 架构列表
odID String 设备唯一标识

🎉 总结

本文详细介绍了 device_info_plus 库在 OpenHarmony 平台上的使用方法,包括:

  1. 环境配置:添加依赖配置
  2. API 使用:获取设备品牌、型号、系统版本等信息
  3. 完整示例:包含信息展示、复制功能的设备信息应用
  4. 问题解决:常见问题的排查和解决方案

通过设备信息获取功能,开发者可以:

  • 统计分析用户设备分布
  • 针对不同设备优化体验
  • 在崩溃日志中记录设备信息
  • 实现设备绑定功能

device_info_plus 提供了跨平台的设备信息获取能力,是 OpenHarmony 平台上获取设备信息的理想选择。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐