Flutter ——device_info_plus详解

23 阅读4分钟

device_info_plus 是 Flutter 生态中最权威的设备信息获取库(官方维护),替代了已废弃的 device_info,支持 Android、iOS、Web、Windows、macOS、Linux、Android TV、watchOS 等几乎所有 Flutter 支持的平台。 库地址 pub.dev/packages/de…

安装

  1. 在项目的 pubspec.yaml 中添加依赖:
dependencies:
  flutter:
    sdk: flutter
    device_info_plus: ^12.3.0 # 建议使用最新版本
  1. 执行命令安装:
flutter pub get

一、核心基础:包架构与初始化

1. 核心类与初始化

device_info_plus 的核心是 DeviceInfoPlugin 单例,通过它可以获取不同平台的设备信息对象:

import 'package:device_info_plus/device_info_plus.dart';

// 1. 创建插件实例(全局唯一)
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();

// 2. 初始化(非必需,但异步操作建议在WidgetsFlutterBinding初始化后执行)
void initDeviceInfo() async {
  WidgetsFlutterBinding.ensureInitialized(); // 无上下文时必须调用
  // 后续获取设备信息的操作...
}

2. 平台与信息类对应表

平台信息获取方法核心信息类适用场景
Androidawait deviceInfoPlugin.androidInfoAndroidDeviceInfo获取安卓设备型号、系统版本、厂商等
iOSawait deviceInfoPlugin.iosInfoIosDeviceInfo获取 iOS 版本、设备型号、UUID 等
Webawait deviceInfoPlugin.webBrowserInfoWebBrowserInfo获取浏览器、操作系统、用户代理等
Windowsawait deviceInfoPlugin.windowsInfoWindowsDeviceInfo获取 Windows 系统版本、处理器、设备名等
macOSawait deviceInfoPlugin.macOsInfoMacOsDeviceInfo获取 Mac 系统版本、机型、内存等
Linuxawait deviceInfoPlugin.linuxInfoLinuxDeviceInfo获取 Linux 发行版、内核版本等
Android TVawait deviceInfoPlugin.androidTvInfoAndroidTvDeviceInfo区分安卓电视 / 普通安卓设备
watchOSawait deviceInfoPlugin.watchOsInfoWatchOsDeviceInfo获取苹果手表信息
Wear OSawait deviceInfoPlugin.wearOsInfoWearOsDeviceInfo获取安卓手表信息
Fuchsiaawait deviceInfoPlugin.fuchsiaInfoFuchsiaDeviceInfo适配 Fuchsia 系统(暂未普及)

二、全平台核心 API 详解

1. Android 平台(AndroidDeviceInfo

最常用的属性(覆盖 90% 场景):

AndroidDeviceInfo androidInfo = await deviceInfoPlugin.androidInfo;
print('=== Android 设备信息 ===');
print('设备型号:${androidInfo.model}'); // 例:Pixel 8 Pro、Redmi K70
print('系统版本:${androidInfo.version.release}'); // 例:14、13
print('API等级:${androidInfo.version.sdkInt}'); // 例:34(Android 14)、33(Android 13)
print('厂商:${androidInfo.manufacturer}'); // 例:Google、Xiaomi、Huawei
print('品牌:${androidInfo.brand}'); // 例:google、xiaomi、huawei
print('设备ID:${androidInfo.id}'); // 设备唯一标识(Android 10+ 无权限获取)
print('产品名:${androidInfo.product}'); // 例:cheetah(Pixel 8 Pro)
print('是否真机:${androidInfo.isPhysicalDevice}'); // true=真机,false=模拟器
print('指纹:${androidInfo.fingerprint}'); // 系统指纹(用于版本判断)
print('硬件名称:${androidInfo.hardware}'); // 例:qcom(高通)
print('支持的ABIs:${androidInfo.supportedAbis}'); // 支持的CPU架构(armeabi-v7a、arm64-v8a等)

2. iOS 平台(IosDeviceInfo

IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
print('=== iOS 设备信息 ===');
print('设备名称:${iosInfo.name}'); // 例:iPhone 15 Pro
print('系统版本:${iosInfo.systemVersion}'); // 例:17.2
print('设备型号:${iosInfo.model}'); // 例:iPhone
print('具体机型:${iosInfo.utsname.machine}'); // 例:iPhone16,1(对应iPhone 15 Pro)
print('是否真机:${iosInfo.isPhysicalDevice}'); // true=真机,false=模拟器
print('设备UUID:${iosInfo.identifierForVendor}'); // 应用厂商唯一标识(卸载重装会变)
print('系统名称:${iosInfo.systemName}'); // 例:iOS、iPadOS
print('电池电量:${iosInfo.batteryLevel}'); // 0.0-1.0(需权限)
print('是否充电:${iosInfo.isCharging}');

3. Web 平台(WebBrowserInfo

WebBrowserInfo webInfo = await deviceInfoPlugin.webBrowserInfo;
print('=== Web 浏览器信息 ===');
print('浏览器名称:${webInfo.browserName}'); // BrowserName.chrome/edge/firefox/safari等
print('浏览器版本:${webInfo.browserVersion}'); // 例:120.0.0.0
print('操作系统:${webInfo.platform}'); // 例:Windows、macOS、Android
print('用户代理:${webInfo.userAgent}'); // 完整UA字符串
print('语言:${webInfo.language}'); // 例:zh-CN
print('是否移动设备:${webInfo.isMobile}'); // true/false

4. Windows 平台(WindowsDeviceInfo

WindowsDeviceInfo windowsInfo = await deviceInfoPlugin.windowsInfo;
print('=== Windows 设备信息 ===');
print('设备名称:${windowsInfo.computerName}'); // 电脑名
print('系统版本:${windowsInfo.systemVersion}'); // 例:10.0.22631
print('处理器名称:${windowsInfo.processorName}'); // 例:Intel(R) Core(TM) i7-12700H
print('内存大小(MB):${windowsInfo.memorySizeInMb}');
print('系统架构:${windowsInfo.systemArchitecture}'); // 例:X64
print('构建号:${windowsInfo.buildNumber}'); // 例:22631

5. macOS 平台(MacOsDeviceInfo

MacOsDeviceInfo macInfo = await deviceInfoPlugin.macOsInfo;
print('=== macOS 设备信息 ===');
print('系统版本:${macInfo.osVersion}'); // 例:14.1.1
print('机型:${macInfo.model}'); // 例:MacBook Pro
print('处理器:${macInfo.processorName}'); // 例:Apple M3 Pro
print('内存大小(GB):${macInfo.memorySizeInGb}');
print('UUID:${macInfo.systemGUID}'); // 系统唯一标识

三、高级用法:封装与实战场景

1. 封装通用工具类(推荐)

将设备信息获取逻辑封装为全局工具类,避免重复代码:

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

class DeviceInfoUtil {
  static final DeviceInfoPlugin _plugin = DeviceInfoPlugin();
  static bool _isInitialized = false;

  // 初始化(全局调用一次即可)
  static Future<void> init() async {
    if (!_isInitialized) {
      WidgetsFlutterBinding.ensureInitialized();
      _isInitialized = true;
    }
  }

  // 通用:获取设备类型(手机/平板/PC/浏览器)
  static Future<String> getDeviceType() async {
    if (kIsWeb) {
      return "Web浏览器";
    }
    // defaultTargetPlatform 获取 设置的类型 
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        final info = await _plugin.androidInfo;
        return info.model.contains("Tablet") ? "安卓平板" : "安卓手机";
      case TargetPlatform.iOS:
        final info = await _plugin.iosInfo;
        return info.model.contains("iPad") ? "iPad" : "iPhone";
      case TargetPlatform.windows:
        return "Windows PC";
      case TargetPlatform.macOS:
        return "Mac电脑";
      case TargetPlatform.linux:
        return "Linux设备";
      default:
        return "未知设备";
    }
  }

  // 通用:获取系统版本(如 "Android 14"、"iOS 17.2")
  static Future<String> getSystemVersion() async {
    if (kIsWeb) {
      final info = await _plugin.webBrowserInfo;
      return info.platform;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        final info = await _plugin.androidInfo;
        return "Android ${info.version.release}";
      case TargetPlatform.iOS:
        final info = await _plugin.iosInfo;
        return "iOS ${info.systemVersion}";
      case TargetPlatform.windows:
        final info = await _plugin.windowsInfo;
        return "Windows ${info.systemVersion}";
      case TargetPlatform.macOS:
        final info = await _plugin.macOsInfo;
        return "macOS ${info.osVersion}";
      default:
        return "未知系统";
    }
  }

  // Android专属:判断是否为鸿蒙系统(鸿蒙伪装成Android)
  static Future<bool> isHarmonyOS() async {
    if (defaultTargetPlatform != TargetPlatform.android) return false;
    final info = await _plugin.androidInfo;
    // 鸿蒙系统的fingerprint或brand会包含harmony相关字段
    return info.fingerprint.contains("harmony") || info.brand.contains("Harmony");
  }
}

// 使用示例
void main() async {
  await DeviceInfoUtil.init();
  String deviceType = await DeviceInfoUtil.getDeviceType();
  String sysVersion = await DeviceInfoUtil.getSystemVersion();
  bool isHarmony = await DeviceInfoUtil.isHarmonyOS();
  print("设备类型:$deviceType");
  print("系统版本:$sysVersion");
  print("是否鸿蒙:$isHarmony");
}

2. 实战场景 1:版本适配

根据系统版本执行不同逻辑(如 Android 权限适配):

// Android 13+ 通知权限适配
Future<void> requestNotificationPermission() async {
  final androidInfo = await deviceInfoPlugin.androidInfo;
  if (androidInfo.version.sdkInt >= 33) { // Android 13 (API 33)
    // 请求POST_NOTIFICATIONS权限
    final status = await Permission.notification.request();
    if (status.isGranted) {
      print("通知权限已授予");
    }
  }
}

3. 实战场景 2:埋点统计

收集设备信息用于用户行为分析(合规前提下):

// 生成埋点用的设备信息JSON
Future<Map<String, dynamic>> getTrackDeviceInfo() async {
  Map<String, dynamic> info = {
    "platform": kIsWeb ? "web" : defaultTargetPlatform.name,
    "device_type": await DeviceInfoUtil.getDeviceType(),
    "system_version": await DeviceInfoUtil.getSystemVersion(),
    "is_emulator": false,
  };

  if (defaultTargetPlatform == TargetPlatform.android) {
    final androidInfo = await deviceInfoPlugin.androidInfo;
    info["manufacturer"] = androidInfo.manufacturer;
    info["model"] = androidInfo.model;
    info["is_emulator"] = !androidInfo.isPhysicalDevice;
  } else if (defaultTargetPlatform == TargetPlatform.iOS) {
    final iosInfo = await deviceInfoPlugin.iosInfo;
    info["model"] = iosInfo.utsname.machine;
    info["is_emulator"] = !iosInfo.isPhysicalDevice;
  }

  return info;
}

四、避坑指南:常见问题与解决方案

1. 权限问题

问题解决方案
Android 10+ 无法获取androidId改用identifierForVendor(iOS)或自定义 UUID(如flutter_secure_storage存储)
iOS 获取电池信息失败需要在Info.plist中添加NSBatteryUsageDescription说明用途
Web 无法获取精准设备型号Web 受限于浏览器沙箱,只能通过 UA 解析(可结合第三方库ua_parser

2. 兼容性问题

问题解决方案
模拟器与真机返回值差异isPhysicalDevice判断,避免模拟器数据干扰
不同 Android 厂商定制系统字段差异优先使用model/manufacturer,避免依赖fingerprint等非标字段
macOS 14+ 获取内存信息失败升级device_info_plus到最新版本(>=10.0.0)

3. 性能与异步问题

  • 设备信息获取是异步操作,不要在build方法中直接调用,建议在initState或全局初始化时获取;
  • 避免频繁调用(如每次点击按钮都获取),建议缓存结果;
  • 无上下文时必须先调用WidgetsFlutterBinding.ensureInitialized(),否则会崩溃。

总结

  1. 核心定位device_info_plus 是 Flutter 多平台设备信息获取的官方首选,替代废弃的device_info,覆盖全平台;
  2. 使用原则:按平台调用对应info方法,优先封装为工具类,异步操作需处理异常和缓存;
  3. 避坑要点:注意权限合规、模拟器 / 真机差异、Android 10+ 设备标识限制,无上下文时先初始化WidgetsFlutterBinding

如果需要针对某一特殊场景(如鸿蒙系统识别、iOS 广告 ID 获取、Web 端设备指纹)的详细代码,我可以进一步补充。