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?
-
1see this link: blog.maskys.com/how-to-get-the-version-build-number– M KarimiCommented Jan 2, 2021 at 9:57
9 Answers
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
- Add this to your package's pubspec.yaml file:
dependencies:
package_info_plus: ^1.0.6
- Import the file into your dart file:
import 'package:package_info_plus/package_info_plus.dart';
- 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;
});
-
1
-
1does 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
-
5Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/package_info) only on release apk Commented Aug 19, 2020 at 16:01
-
2If 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
-
4If 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
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
-
I don't see how this is different than accepted answer?– user6274128Commented 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.– SuragchCommented Sep 10, 2019 at 13:54
-
1Sorry I didn't see that, you are right, your answer should be the accepted one, +1 from me.– user6274128Commented Sep 10, 2019 at 16:48
-
package_info_plus
- nice. Thanks so much for sharing. Like it more thanpackage_info
as it supports more platforms.– Björn WCommented Jul 30, 2021 at 8:06 -
More about the deprecated packages plugins here: github.com/flutter/plugins/blob/master/README.md#deprecated Commented Aug 15, 2021 at 10:10
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();
}
},
),
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.
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
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;
});
}
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.
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);
}
),
],
)
);
-
new_version plugin is not continued anymore, please delete your answer or hide it for not mislead developers– TimurCommented Jun 10 at 13:01
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
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;