基础入门 Flutter for OpenHarmony:package_info_plus 应用信息获取详解

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
🎯 欢迎来到 Flutter for OpenHarmony 社区!本文将深入讲解 Flutter 中 package_info_plus 应用信息获取组件的使用方法,带你全面掌握在应用中获取版本号、包名等应用元数据的各种技巧。


一、package_info_plus 组件概述

在 Flutter for OpenHarmony 应用开发中,package_info_plus 是一个非常实用的应用信息获取插件,它允许开发者获取当前应用的各种元数据信息,如版本号、构建号、包名、应用名称等。这些信息在版本管理、更新检测、用户反馈、统计分析等场景中非常重要。

📋 package_info_plus 组件特点

特点 说明
跨平台支持 支持 Android、iOS、Web、Windows、macOS、Linux、OpenHarmony
信息丰富 提供版本号、构建号、包名、应用名称等多种信息
简单易用 API 简洁直观,一行代码即可获取信息
无需权限 不需要任何特殊权限即可使用
实时获取 运行时动态获取应用信息

💡 使用场景:版本检查、应用更新、关于页面、用户反馈、统计分析、日志记录等。


二、OpenHarmony 平台适配说明

2.1 兼容性信息

本项目基于 package_info_plus@8.1.0 开发,适配 Flutter 3.27.5-ohos-1.0.4。

2.2 支持的功能

在 OpenHarmony 平台上,package_info_plus 支持以下功能:

功能 说明 OpenHarmony 支持
应用名称 获取应用显示名称 ✅ yes
包名 获取应用包标识 ✅ yes
版本号 获取应用版本号 ✅ yes
构建号 获取应用构建号 ✅ yes
应用签名 获取应用签名信息 ✅ yes

三、项目配置与安装

3.1 添加依赖配置

首先,需要在你的 Flutter 项目的 pubspec.yaml 文件中添加 package_info_plus 依赖。

打开项目根目录下的 pubspec.yaml 文件,找到 dependencies 部分,添加以下配置:

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter

  # 添加 package_info_plus 依赖(OpenHarmony 适配版本)
  package_info_plus:
    git:
      url: "https://atomgit.com/openharmony-sig/flutter_plus_plugins.git"
      path: "packages/package_info_plus/package_info_plus"
      ref: "br_package_info_plus-v8.1.0_ohos"

配置说明:

  • 使用 git 方式引用开源鸿蒙适配的 flutter_plus_plugins 仓库
  • url:指定 AtomGit 托管的仓库地址
  • path:指定 package_info_plus 包的具体路径
  • ref:指定适配 OpenHarmony 的分支版本
  • 本项目基于 package_info_plus@8.1.0 开发,适配 Flutter 3.27.5-ohos-1.0.4

⚠️ 重要:对于 OpenHarmony 平台,必须使用 git 方式引用适配版本,不能直接使用 pub.dev 的版本号。

3.2 下载依赖

配置完成后,需要在项目根目录执行以下命令下载依赖:

bash 复制代码
flutter pub get

执行成功后,你会看到类似以下的输出:

复制代码
Running "flutter pub get" in my_cross_platform_app...
Resolving dependencies...
Got dependencies!

3.3 依赖自动配置说明

执行 flutter pub get 后,OpenHarmony 平台的依赖会自动配置到 ohos/entry/oh-package.json5 文件中。Flutter 构建系统会自动处理平台相关的依赖配置,无需手动干预。


四、package_info_plus 基础用法

4.1 导入库

在使用 package_info_plus 之前,需要先导入库:

dart 复制代码
import 'package:package_info_plus/package_info_plus.dart';

4.2 获取应用信息

获取应用信息的基本方式:

dart 复制代码
Future<PackageInfo> _getPackageInfo() async {
  PackageInfo packageInfo = await PackageInfo.fromPlatform();
  return packageInfo;
}

4.3 获取各项信息

dart 复制代码
PackageInfo packageInfo = await PackageInfo.fromPlatform();

String appName = packageInfo.appName;           // 应用名称
String packageName = packageInfo.packageName;   // 包名
String version = packageInfo.version;           // 版本号
String buildNumber = packageInfo.buildNumber;   // 构建号
String buildSignature = packageInfo.buildSignature; // 应用签名

4.4 在 Widget 中使用

dart 复制代码
class AppInfoWidget extends StatefulWidget {
  const AppInfoWidget({super.key});

  @override
  State<AppInfoWidget> createState() => _AppInfoWidgetState();
}

class _AppInfoWidgetState extends State<AppInfoWidget> {
  PackageInfo? _packageInfo;

  @override
  void initState() {
    super.initState();
    _initPackageInfo();
  }

  Future<void> _initPackageInfo() async {
    final info = await PackageInfo.fromPlatform();
    setState(() {
      _packageInfo = info;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_packageInfo == null) {
      return const CircularProgressIndicator();
    }
    
    return Column(
      children: [
        Text('应用名称: ${_packageInfo!.appName}'),
        Text('版本号: ${_packageInfo!.version}'),
        Text('构建号: ${_packageInfo!.buildNumber}'),
      ],
    );
  }
}

五、常用 API 详解

5.1 PackageInfo 类

PackageInfo 类包含以下属性:

属性 类型 说明
appName String 应用显示名称
packageName String 应用包名
version String 应用版本号
buildNumber String 应用构建号
buildSignature String 应用签名(仅 Android)
installerStore String? 安装来源商店

5.2 fromPlatform 方法

从平台获取应用信息:

dart 复制代码
static Future<PackageInfo> fromPlatform()

返回值:

  • 返回 PackageInfo 对象,包含应用的各种信息

5.3 使用示例

dart 复制代码
Future<void> printAppInfo() async {
  PackageInfo packageInfo = await PackageInfo.fromPlatform();
  
  print('应用名称: ${packageInfo.appName}');
  print('包名: ${packageInfo.packageName}');
  print('版本号: ${packageInfo.version}');
  print('构建号: ${packageInfo.buildNumber}');
  print('签名: ${packageInfo.buildSignature}');
}

六、实际应用场景

6.1 关于页面

dart 复制代码
class AboutPage extends StatefulWidget {
  const AboutPage({super.key});

  @override
  State<AboutPage> createState() => _AboutPageState();
}

class _AboutPageState extends State<AboutPage> {
  PackageInfo? _packageInfo;

  @override
  void initState() {
    super.initState();
    _loadPackageInfo();
  }

  Future<void> _loadPackageInfo() async {
    final info = await PackageInfo.fromPlatform();
    setState(() {
      _packageInfo = info;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('关于')),
      body: _packageInfo == null
          ? const Center(child: CircularProgressIndicator())
          : SingleChildScrollView(
              padding: const EdgeInsets.all(20),
              child: Column(
                children: [
                  const SizedBox(height: 20),
                  Container(
                    width: 80,
                    height: 80,
                    decoration: BoxDecoration(
                      color: Theme.of(context).primaryColor,
                      borderRadius: BorderRadius.circular(16),
                    ),
                    child: const Icon(Icons.apps, size: 48, color: Colors.white),
                  ),
                  const SizedBox(height: 16),
                  Text(
                    _packageInfo!.appName,
                    style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 8),
                  Text(
                    '版本 ${_packageInfo!.version} (${_packageInfo!.buildNumber})',
                    style: const TextStyle(color: Colors.grey),
                  ),
                  const SizedBox(height: 32),
                  _buildInfoTile('应用名称', _packageInfo!.appName),
                  _buildInfoTile('包名', _packageInfo!.packageName),
                  _buildInfoTile('版本号', _packageInfo!.version),
                  _buildInfoTile('构建号', _packageInfo!.buildNumber),
                  const SizedBox(height: 20),
                  const Text(
                    '© 2024 Flutter for OpenHarmony',
                    style: TextStyle(color: Colors.grey),
                  ),
                ],
              ),
            ),
    );
  }

  Widget _buildInfoTile(String label, String value) {
    return Container(
      margin: const EdgeInsets.only(bottom: 12),
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        borderRadius: BorderRadius.circular(12),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(label, style: const TextStyle(color: Colors.grey)),
          Text(value, style: const TextStyle(fontWeight: FontWeight.w500)),
        ],
      ),
    );
  }
}

6.2 版本检查与更新

dart 复制代码
class VersionCheckService {
  static const String _latestVersion = '2.0.0';
  static const String _updateUrl = 'https://example.com/download';

  Future<Map<String, dynamic>> checkForUpdate() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    String currentVersion = packageInfo.version;
    
    bool hasUpdate = _compareVersions(_latestVersion, currentVersion) > 0;
    
    return {
      'hasUpdate': hasUpdate,
      'currentVersion': currentVersion,
      'latestVersion': _latestVersion,
      'updateUrl': _updateUrl,
    };
  }

  int _compareVersions(String v1, String v2) {
    List<int> parts1 = v1.split('.').map(int.parse).toList();
    List<int> parts2 = v2.split('.').map(int.parse).toList();
    
    for (int i = 0; i < 3; i++) {
      if (parts1[i] > parts2[i]) return 1;
      if (parts1[i] < parts2[i]) return -1;
    }
    return 0;
  }
}

6.3 用户反馈

dart 复制代码
class FeedbackPage extends StatefulWidget {
  const FeedbackPage({super.key});

  @override
  State<FeedbackPage> createState() => _FeedbackPageState();
}

class _FeedbackPageState extends State<FeedbackPage> {
  PackageInfo? _packageInfo;
  final TextEditingController _feedbackController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _loadPackageInfo();
  }

  Future<void> _loadPackageInfo() async {
    final info = await PackageInfo.fromPlatform();
    setState(() {
      _packageInfo = info;
    });
  }

  Future<void> _submitFeedback() async {
    String feedback = _feedbackController.text;
    String deviceInfo = '''
应用版本: ${_packageInfo?.version ?? 'unknown'}
构建号: ${_packageInfo?.buildNumber ?? 'unknown'}
包名: ${_packageInfo?.packageName ?? 'unknown'}
反馈内容: $feedback
''';
    
    // 提交反馈到服务器
    debugPrint('提交反馈:\n$deviceInfo');
    
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('感谢您的反馈!')),
      );
      Navigator.pop(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('意见反馈')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(8),
              ),
              child: Row(
                children: [
                  const Icon(Icons.info_outline, size: 16, color: Colors.grey),
                  const SizedBox(width: 8),
                  Text(
                    '当前版本: ${_packageInfo?.version ?? "加载中..."}',
                    style: const TextStyle(color: Colors.grey),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _feedbackController,
              maxLines: 5,
              decoration: const InputDecoration(
                hintText: '请输入您的反馈意见...',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: _submitFeedback,
                child: const Text('提交反馈'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

6.4 日志记录

dart 复制代码
class Logger {
  static PackageInfo? _packageInfo;

  static Future<void> init() async {
    _packageInfo = await PackageInfo.fromPlatform();
  }

  static void log(String message, {String level = 'INFO'}) {
    String timestamp = DateTime.now().toIso8601String();
    String version = _packageInfo?.version ?? 'unknown';
    
    String logMessage = '[$timestamp][$level][v$version] $message';
    debugPrint(logMessage);
  }

  static void error(String message, [Object? error, StackTrace? stackTrace]) {
    log('$message\nError: $error\nStackTrace: $stackTrace', level: 'ERROR');
  }
}

// 使用示例
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Logger.init();
  
  Logger.log('应用启动');
  runApp(const MyApp());
}

6.5 设置页面

dart 复制代码
class SettingsPage extends StatelessWidget {
  const SettingsPage({super.key});

  Future<PackageInfo> _getPackageInfo() async {
    return await PackageInfo.fromPlatform();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('设置')),
      body: FutureBuilder<PackageInfo>(
        future: _getPackageInfo(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return const Center(child: CircularProgressIndicator());
          }
          
          final packageInfo = snapshot.data!;
          
          return ListView(
            children: [
              _buildSection('通用'),
              _buildTile(Icons.info, '关于', () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (_) => const AboutPage()),
                );
              }),
              _buildTile(Icons.update, '检查更新', () {
                _checkUpdate(context, packageInfo.version);
              }),
              _buildTile(Icons.feedback, '意见反馈', () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (_) => const FeedbackPage()),
                );
              }),
              _buildSection('版本信息'),
              _buildInfoItem('当前版本', packageInfo.version),
              _buildInfoItem('构建号', packageInfo.buildNumber),
              _buildInfoItem('包名', packageInfo.packageName),
            ],
          );
        },
      ),
    );
  }

  Widget _buildSection(String title) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 20, 16, 8),
      child: Text(
        title,
        style: const TextStyle(
          color: Colors.grey,
          fontSize: 12,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }

  Widget _buildTile(IconData icon, String title, VoidCallback onTap) {
    return ListTile(
      leading: Icon(icon),
      title: Text(title),
      trailing: const Icon(Icons.chevron_right),
      onTap: onTap,
    );
  }

  Widget _buildInfoItem(String label, String value) {
    return ListTile(
      title: Text(label),
      subtitle: Text(value),
    );
  }

  void _checkUpdate(BuildContext context, String currentVersion) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('当前已是最新版本 $currentVersion')),
    );
  }
}

七、完整示例代码

下面是一个完整的示例应用,展示了 package_info_plus 的各种用法:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PackageInfo Plus 示例',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF6366F1)),
        useMaterial3: true,
      ),
      home: const PackageInfoDemoPage(),
    );
  }
}

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

  @override
  State<PackageInfoDemoPage> createState() => _PackageInfoDemoPageState();
}

class _PackageInfoDemoPageState extends State<PackageInfoDemoPage> {
  PackageInfo? _packageInfo;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadPackageInfo();
  }

  Future<void> _loadPackageInfo() async {
    try {
      final info = await PackageInfo.fromPlatform();
      setState(() {
        _packageInfo = info;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _isLoading = false;
      });
      debugPrint('获取应用信息失败: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('PackageInfo Plus 示例'),
        centerTitle: true,
        elevation: 0,
      ),
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFFE8F4FF),
              Color(0xFFF8F9FF),
            ],
          ),
        ),
        child: SafeArea(
          child: _isLoading
              ? const Center(child: CircularProgressIndicator())
              : _packageInfo == null
                  ? const Center(child: Text('获取应用信息失败'))
                  : SingleChildScrollView(
                      padding: const EdgeInsets.all(20),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          _buildAppCard(),
                          const SizedBox(height: 24),
                          _buildSectionTitle('应用信息'),
                          const SizedBox(height: 12),
                          _buildInfoGrid(),
                          const SizedBox(height: 24),
                          _buildSectionTitle('功能示例'),
                          const SizedBox(height: 12),
                          _buildFeatureButtons(),
                        ],
                      ),
                    ),
        ),
      ),
    );
  }

  Widget _buildAppCard() {
    return Container(
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
        ),
        borderRadius: BorderRadius.circular(20),
        boxShadow: [
          BoxShadow(
            color: const Color(0xFF6366F1).withOpacity(0.3),
            blurRadius: 20,
            offset: const Offset(0, 10),
          ),
        ],
      ),
      child: Column(
        children: [
          Container(
            width: 80,
            height: 80,
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.2),
              borderRadius: BorderRadius.circular(20),
            ),
            child: const Icon(Icons.apps, size: 48, color: Colors.white),
          ),
          const SizedBox(height: 16),
          Text(
            _packageInfo!.appName,
            style: const TextStyle(
              color: Colors.white,
              fontSize: 24,
              fontWeight: FontWeight.bold,
            ),
          ),
          const SizedBox(height: 8),
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
            decoration: BoxDecoration(
              color: Colors.white.withOpacity(0.2),
              borderRadius: BorderRadius.circular(20),
            ),
            child: Text(
              'v${_packageInfo!.version} (${_packageInfo!.buildNumber})',
              style: const TextStyle(color: Colors.white),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSectionTitle(String title) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
        ),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        title,
        style: const TextStyle(
          color: Colors.white,
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }

  Widget _buildInfoGrid() {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.05),
            blurRadius: 10,
          ),
        ],
      ),
      child: Column(
        children: [
          _buildInfoRow('应用名称', _packageInfo!.appName, Icons.apps),
          const Divider(height: 24),
          _buildInfoRow('包名', _packageInfo!.packageName, Icons.inventory_2),
          const Divider(height: 24),
          _buildInfoRow('版本号', _packageInfo!.version, Icons.verified),
          const Divider(height: 24),
          _buildInfoRow('构建号', _packageInfo!.buildNumber, Icons.build),
          if (_packageInfo!.buildSignature.isNotEmpty) ...[
            const Divider(height: 24),
            _buildInfoRow('签名', _truncateSignature(_packageInfo!.buildSignature), Icons.key),
          ],
        ],
      ),
    );
  }

  Widget _buildInfoRow(String label, String value, IconData icon) {
    return Row(
      children: [
        Container(
          padding: const EdgeInsets.all(8),
          decoration: BoxDecoration(
            color: const Color(0xFF6366F1).withOpacity(0.1),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Icon(icon, size: 20, color: const Color(0xFF6366F1)),
        ),
        const SizedBox(width: 12),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(label, style: const TextStyle(color: Colors.grey, fontSize: 12)),
              const SizedBox(height: 2),
              Text(
                value,
                style: const TextStyle(fontWeight: FontWeight.w500),
                overflow: TextOverflow.ellipsis,
              ),
            ],
          ),
        ),
      ],
    );
  }

  String _truncateSignature(String signature) {
    if (signature.length > 20) {
      return '${signature.substring(0, 20)}...';
    }
    return signature;
  }

  Widget _buildFeatureButtons() {
    return Column(
      children: [
        Row(
          children: [
            Expanded(
              child: _buildFeatureCard(
                '关于页面',
                Icons.info,
                Colors.blue,
                () => _showAboutDialog(),
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildFeatureCard(
                '版本检查',
                Icons.update,
                Colors.green,
                () => _checkForUpdate(),
              ),
            ),
          ],
        ),
        const SizedBox(height: 12),
        Row(
          children: [
            Expanded(
              child: _buildFeatureCard(
                '复制信息',
                Icons.copy,
                Colors.purple,
                () => _copyInfo(),
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: _buildFeatureCard(
                '分享信息',
                Icons.share,
                Colors.orange,
                () => _shareInfo(),
              ),
            ),
          ],
        ),
      ],
    );
  }

  Widget _buildFeatureCard(
    String title,
    IconData icon,
    Color color,
    VoidCallback onTap,
  ) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(16),
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.05),
              blurRadius: 10,
            ),
          ],
        ),
        child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: color.withOpacity(0.1),
                borderRadius: BorderRadius.circular(12),
              ),
              child: Icon(icon, color: color, size: 28),
            ),
            const SizedBox(height: 12),
            Text(
              title,
              style: const TextStyle(fontWeight: FontWeight.w500),
            ),
          ],
        ),
      ),
    );
  }

  void _showAboutDialog() {
    showAboutDialog(
      context: context,
      applicationName: _packageInfo!.appName,
      applicationVersion: '${_packageInfo!.version} (${_packageInfo!.buildNumber})',
      applicationIcon: Container(
        width: 48,
        height: 48,
        decoration: BoxDecoration(
          color: const Color(0xFF6366F1),
          borderRadius: BorderRadius.circular(12),
        ),
        child: const Icon(Icons.apps, color: Colors.white),
      ),
      children: [
        Text('包名: ${_packageInfo!.packageName}'),
      ],
    );
  }

  void _checkForUpdate() {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('当前已是最新版本 ${_packageInfo!.version}'),
        backgroundColor: Colors.green,
      ),
    );
  }

  void _copyInfo() {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('应用信息已复制到剪贴板')),
    );
  }

  void _shareInfo() {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('分享功能已触发')),
    );
  }
}

八、常见问题与解决方案

8.1 获取信息失败

问题原因:

  • 平台未正确初始化
  • 依赖未正确配置

解决方案:

dart 复制代码
// 确保在 Widget 构建后获取信息
Future<void> _loadPackageInfo() async {
  try {
    final info = await PackageInfo.fromPlatform();
    setState(() {
      _packageInfo = info;
    });
  } catch (e) {
    debugPrint('获取应用信息失败: $e');
  }
}

8.2 版本号显示不正确

问题原因:

  • pubspec.yaml 中的版本号格式不正确
  • 平台配置文件中的版本号未更新

解决方案:

确保 pubspec.yaml 中的版本号格式正确:

yaml 复制代码
version: 1.0.0+1

格式说明:版本号+构建号

8.3 应用名称显示为空

问题原因:

  • OpenHarmony 平台配置中未设置应用名称

解决方案:

检查 OpenHarmony 配置文件 ohos/entry/src/main/module.json5

json 复制代码
{
  "module": {
    "abilities": [
      {
        "label": "你的应用名称"
      }
    ]
  }
}

九、总结

package_info_plus 是 Flutter for OpenHarmony 应用开发中常用的应用信息获取组件。通过本文的学习,我们掌握了:

  1. 基础用法:获取应用名称、版本号、包名等信息
  2. API 详解:PackageInfo 类的属性和方法
  3. 实际应用:关于页面、版本检查、用户反馈、日志记录等场景
  4. 常见问题:获取失败、版本号不正确等问题的解决方案

💡 开发建议:使用 package_info_plus 时应注意:

  • 在应用启动时初始化并缓存信息
  • 版本号格式应遵循语义化版本规范
  • 在用户反馈中附带版本信息便于排查问题
  • 定期更新版本号以反映应用变更

相关推荐
恋猫de小郭12 小时前
Flutter 正在计划提供 Packaged AI Assets 的支持,让你的包/插件可以更好被 AI 理解和选择
android·前端·flutter
无巧不成书021812 小时前
【Harmonyos】Flutter开源鸿蒙跨平台训练营 Day19 分布式架构开发指南
flutter·开源·harmonyos
钛态14 小时前
Flutter for OpenHarmony 实战:flex_color_scheme 打造极致鸿蒙美学 UI
flutter·ui·harmonyos
sdff1139617 小时前
【HarmonyOS】Flutter适配鸿蒙多屏异构UI开发实战指南
flutter·ui·harmonyos
lqj_本人19 小时前
Flutter三方库适配OpenHarmony【apple_product_name】getProductName方法实战应用
flutter
钛态20 小时前
Flutter for OpenHarmony 实战:Stack Trace — 异步堆栈调试专家
android·flutter·ui·华为·架构·harmonyos
哈__20 小时前
Flutter for OpenHarmony 三方库鸿蒙适配实战:flutter_video_info
flutter·华为·harmonyos
lqj_本人20 小时前
Flutter三方库适配OpenHarmony【apple_product_name】环境搭建与依赖配置
flutter
钛态20 小时前
Flutter for OpenHarmony 实战:YAML — 结构化配置解析专家
flutter·ui·华为·架构·harmonyos