218

I am currently developing an application which is currently in beta mode. Due to this, I would like to show them what version they are on. For example, "v1.0b10 - iOS". So far, I have got this code: Text("Build: V1.0b10 - " + (Platform.isIOS ? "iOS" : "Android")). How would I be able to get the build version and number within flutter?

1

9 Answers 9

364

You can use package_info_plus.

The versions are extracted from:

Android:

build.gradle, versionCode and versionName

iOS:

Info.plist, CFBundleVersion

Usage

Add the dependency

  1. Add this to your package's pubspec.yaml file:
dependencies:
  package_info_plus: ^1.0.6
  1. Import the file into your dart file:
import 'package:package_info_plus/package_info_plus.dart';
  1. if your method is marked as async:
PackageInfo packageInfo = await PackageInfo.fromPlatform();

String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;

If you don't want to use await/async:

PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
  String appName = packageInfo.appName;
  String packageName = packageInfo.packageName;
  String version = packageInfo.version;
  String buildNumber = packageInfo.buildNumber;
});
8
  • 1
    @Wajidkhan, 1.0.0 is the version number and 6 is the build number. See this.
    – Suragch
    Commented Jan 9, 2020 at 0:13
  • 1
    does this means I need to manually modify/maintain different versions for iOS and Android? is there a unified place? Commented May 30, 2020 at 12:44
  • 5
    Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/package_info) only on release apk
    – Jithin Joy
    Commented Aug 19, 2020 at 16:01
  • 2
    If you want your app working on Web, Android and IOS use "package_info_plus" instead. pub.dev/packages/package_info_plus. Commented Nov 22, 2020 at 13:50
  • 4
    If you get Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/package_info) error, try to reinstall the app completely Commented Jan 6, 2023 at 8:42
114

Note: This answer has been updated to reflect the fact that the package_info plugin is deprecated and redirects to package_info_plus.

Version name and build number

At development time, you can easily find the version name and build number of a Flutter or Dart project by inspecting pubspec.yaml. Here is an example:

version: 1.1.0+2

This is case the version name is 1.1.0 and the build number is 2.

However, if you want to get these values at runtime, you should use a plugin.

Add the dependency

In pubspec.yaml add the package_info_plus package.

dependencies:
  package_info_plus: ^1.0.2

Update the version number to the current one.

Import the package

In the file that you need it, add the following import.

import 'package:package_info_plus/package_info_plus.dart';

Get the version name and code

In your code you can get the app version name and code like this:

PackageInfo packageInfo = await PackageInfo.fromPlatform();
String version = packageInfo.version;
String code = packageInfo.buildNumber;

See also

5
  • I don't see how this is different than accepted answer?
    – user6274128
    Commented Sep 9, 2019 at 15:52
  • 11
    @Volleyball, at the time I answered the question, the accepted answer was much shorter (check the edit history). Later that user added a lot of content so they are basically the same now.
    – Suragch
    Commented Sep 10, 2019 at 13:54
  • 1
    Sorry I didn't see that, you are right, your answer should be the accepted one, +1 from me.
    – user6274128
    Commented Sep 10, 2019 at 16:48
  • package_info_plus - nice. Thanks so much for sharing. Like it more than package_info as it supports more platforms.
    – Björn W
    Commented Jul 30, 2021 at 8:06
  • More about the deprecated packages plugins here: github.com/flutter/plugins/blob/master/README.md#deprecated
    – Son Nguyen
    Commented Aug 15, 2021 at 10:10
17

install package_info_plus, then you can use it directly with future builder in your widget tree:

 FutureBuilder<PackageInfo>(
              future: PackageInfo.fromPlatform(),
              builder: (context, snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.done:
                    return Align(
                      alignment: Alignment.bottomCenter,
                      child: Text(
                        'Version: ${snapshot.data!.version}',),
                      );
                  default:
                    return const SizedBox();
                }
              },
            ),
7

RE the multiple references to package_info, please note that this package has been deprecated and the recommended replacement is the Flutter Community Plus Plugins version, package_info_plus.

1
  • version number for me is always unknown
    – chitgoks
    Commented Apr 23, 2022 at 1:46
5

For using it from command line or CLI, you need a pure Dart code.

I used the following script:

// ignore_for_file: avoid_print
import 'dart:io';

import 'package:path/path.dart';
import 'package:yaml/yaml.dart';

String pathToYaml = join(dirname(Platform.script.toFilePath()), '../pubspec.yaml');

Future<YamlMap> loadPubspec() async => loadYaml(await File(pathToYaml).readAsString());

void main() async {
  var pubspec = await loadPubspec();
  print(pubspec['version'].toString().split('+')[0]);
}

You can run it from the project root folder:

dart run scripts/get_version_name.dart
0
3

In Flutter mobile applications the version number is in pubspec.yaml file. like below:

version: 1.0.0+1

To get the version name and code, add the package_info dependency into pubspec.yaml file, like below:

dependencies:
  package_info: ^0.4.0+16

And

import 'package:package_info/package_info.dart'; // import the package_info

Future<void> _initPackageInfo() async {
    final _packageInfo = await PackageInfo.fromPlatform();
    setState(() {
          String AppName = _packageInfo.appName;
          String PackageName = _packageInfo.packageName;
          String AppVersion = _packageInfo.version;
          String BuildNumber = _packageInfo.buildNumber;
          String BuildSignature = _packageInfo.buildSignature;
    });
  }
2

You can try new_version plugin. Using this plugin you can get installed App Version, Playstore App Version and app url which can redirect to playstore.

New Version Plugin

void versionCheck() async {
    final NewVersion newVersion = NewVersion(context: context);
    VersionStatus versionStatus = await newVersion.getVersionStatus();
    if (versionStatus != null && versionStatus.canUpdate) {
      await ConfirmDialog(
          context: context,
          title: 'Update Available',
          body: Text('A new version, ${versionStatus.storeVersion}, is available.'),
          acceptButton: 'Update Now',
          cancelButton: 'Update Later'
      ).then((ConfirmAction res) async {
        if (res == ConfirmAction.CONFIRM && await canLaunch(versionStatus.appStoreLink)) {
          await launch(versionStatus.appStoreLink, forceWebView: false);
        }
      });
    }
  }

Custom Alert Dialog Box

enum ConfirmAction{ CONFIRM, CANCEL }
Future<ConfirmAction> ConfirmDialog({
  BuildContext context,
  String title,
  Widget body,
  String acceptButton,
  String cancelButton
})
=> showDialog(
    context: context,
    barrierDismissible: false,
    builder: (BuildContext context) => AlertDialog(
      title: Wrap(
        crossAxisAlignment: WrapCrossAlignment.center,
        spacing: 4,
        children: <Widget>[
          Text(title)
        ],
      ),
      content: Wrap(
        runSpacing: 10,
        children: <Widget>[
          body,
        ],
      ),
      actions: <Widget>[
        FlatButton(
            padding: EdgeInsets.all(6),
            child: Text(acceptButton ?? 'Confirm'),
            onPressed: (){
              Navigator.of(context, rootNavigator: true).pop(ConfirmAction.CONFIRM);
            }
        ),
        FlatButton(
            padding: EdgeInsets.all(6),
            child: Text(cancelButton ?? 'Cancel'),
            onPressed: (){
              Navigator.of(context, rootNavigator: true).pop(ConfirmAction.CANCEL);
            }
        ),
      ],
    )
);
1
  • new_version plugin is not continued anymore, please delete your answer or hide it for not mislead developers
    – Timur
    Commented Jun 10 at 13:01
1

Using a plugin that have native code and method channel between dart and Kotlin/Swift etc... just to get basic data like the build number might be a little bit overkill, plugins has many build issues problems, when new things come out you will have to wait or send them PR yourself to update it

but there is another solution which is to having a script that extract the data from pubspec.yaml file into dart code, you will have to run that script every time you change the version in pubspec.yaml or when building the release app

here is a little script I wrote:


import 'dart:io' show File;

import 'package:yaml/yaml.dart';

// Extract data like the app version from pubspec.yaml file into dart code

void main(List<String> args) async {
  final pubspecYamlFile = File('./pubspec.yaml');
  final pubspecYamlContent = await pubspecYamlFile.readAsString();
  final yamlDocument = loadYaml(pubspecYamlContent) as YamlMap;
  final version = yamlDocument['version'].toString();
  final appVersion = version.split('+')[0];
  final appBuildNumber = version.split('+')[1];

  final repository = yamlDocument['repository'].toString();

  final generatedDartFile = '''
const appVersion = '$appVersion';
const appBuildNumber = $appBuildNumber;
const repository = '$repository';
''';
  final file = File('./lib/gen/pubspec.g.dart');
  if (!(await file.exists())) {
    await file.create(recursive: true);
  }
  await file.writeAsString(generatedDartFile);
}


I might create a dev package and publish it in pubspec because I need it in multiple projects

also this way you can get the data in your widget without using FutureBuilder widget because it's not a Future

Edit: There is already a dev package for this, check pubspec_extract and pubspec_generator

0

you can also do this using method channel

In your MainActivity.kt add this;

package "your package name"
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "version_info"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "getAppVersion" -> {
                    val versionName = BuildConfig.VERSION_NAME
                    result.success(versionName)
                }
                "getBuildNumber" -> {
                    val versionCode = BuildConfig.VERSION_CODE
                    result.success(versionCode.toString())
                }
                else -> result.notImplemented()
            }
        }
    }
}

For IOS, add this in your AppDelegate.swift

   let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
let versionChannel = FlutterMethodChannel(name: "version_info", binaryMessenger: controller.binaryMessenger)

versionChannel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
  if call.method == "getAppVersion" {
    if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
      result(version)
    } else {
      result(FlutterError(code: "UNAVAILABLE",
                          message: "App version unavailable",
                          details: nil))
    }
  } else if call.method == "getBuildNumber" {
    if let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
      result(buildNumber)
    } else {
      result(FlutterError(code: "UNAVAILABLE",
                          message: "Build number unavailable",
                          details: nil))
    }
  } else {
    result(FlutterMethodNotImplemented)
  }
}

Now in make a dart class to invoke the method channels

   class VersionInfo {
  static const MethodChannel _channel = MethodChannel('version_info');

  static Future<String> get appVersion async {
    final String version = await _channel.invokeMethod('getAppVersion');
    return version;
  }

  static Future<String> get buildNumber async {
    final String buildNumber = await _channel.invokeMethod('getBuildNumber');
    return buildNumber;
  }
}

Now you can easily get your app version and version code
    String appVersion = await VersionInfo.appVersion;
    String appBuildNumber = await VersionInfo.buildNumber;

Not the answer you're looking for? Browse other questions tagged or ask your own question.