FlutterでのOS判定、端末情報、バージョン情報取得や比較のあれこれ【忙しい人向け】
はじめに
FlutterでのOS判定、端末情報、バージョン情報取得などパッケージも含めると充実しています。よく使いそうなあれ?これどうやる?どう取得する?を簡単にまとめた記事になります。
対象
モバイルのみ(Android/iOS)
OS判定したい
これはよく使われているコードだと思うのですがdart:ioで用意されてるOS判定のクラスです
// Android
if (Platform.isAndroid) {
// Androidで実行したい処理
}
// iOS
if (Platform.isIOS) {
// iOSで実行したい処理
}
ただ、Widgetの出しわけのためのOS判定は以下記事にも記載がありますが、Themeを使った判定の方が良さそうです
Theme.of(context).platform == TargetPlatform.android // Android
Theme.of(context).platform == TargetPlatform.iOS // iOS
アプリ名を取得したい
package_info_plusパッケージで取得できます (package_infoの方はもうメンテされないので、package_info_plusの方を使いましょう)
final packageInfo = await PackageInfo.fromPlatform();
final appName = packageInfo.appName; // String
アプリバージョンを取得したい
これもpackage_info_plusパッケージで取得できます
final packageInfo = await PackageInfo.fromPlatform();
final version = packageInfo.version; // String
アプリのビルド番号を取得したい
これもpackage_info_plusパッケージで取得できます
final packageInfo = await PackageInfo.fromPlatform();
final buildNumber = packageInfo.buildNumber; // String
OSバージョンを取得したい
これはdevice_info_plusパッケージで取得できます(これもdevice_infoの方はメンテされないので、device_info_plusを使いましょう)
こんな感じで取得できます
// Android
final androidInfo = await deviceInfo.androidInfo;
final androidOsVersion = androidInfo.version.release!;
// iOS
final iosInfo = await deviceInfo.iosInfo;
final iosOsVersion = iosInfo.systemVersion!;
上記のOS単位での取得できるメソッドが用意されてますが、利用者側にOSを意識せずに端末情報を取得するメソッドがあります
final deviceInfoPlugin = DeviceInfoPlugin();
final deviceInfo = await deviceInfoPlugin.deviceInfo;
以下内部コードを見るとOSごとに分岐しています
また、Riverpodを組み合わせたやり方で非同期で取得に時間がかかるものに対して、起動時に事前に取得してProviderScopeでoverridesさせるやる方もあるので自分はこんな感じにしてます(どっちでもいいかも)
※ Riverpodはv1.0.0以上
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'app.dart';
import 'samples/device_and_packge_info/device_info_provider.dart';
import 'samples/device_and_packge_info/package_info_provider.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// BaseDeviceInfoというabstract classが定義されていて
// 各DeviceInfoクラス(AndroidDeviceInfo,IosDeviceInfoで)にimplementsされている
late BaseDeviceInfo deviceInfo;
late PackageInfo packageInfo; // PackageInfoinfoも同様に可能
await Future.wait([
Future(() async {
deviceInfo = await DeviceInfoPlugin().deviceInfo;
}),
Future(() async {
packageInfo = await PackageInfo.fromPlatform();
}),
]);
runApp(
ProviderScope(
overrides: [
deviceInfoProvider.overrideWithValue(deviceInfo),
packageInfoProvider.overrideWithValue(packageInfo),
],
/// 省略
),
);
}
Providerの宣言は以下みたいな感じです
import 'package:device_info_plus/device_info_plus.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:package_info_plus/package_info_plus.dart';
final deviceInfoProvider = Provider<BaseDeviceInfo>(
(_) => throw UnimplementedError(),
);
final packageInfoProvider = Provider<PackageInfo>(
(ref) => throw UnimplementedError(),
);
利用時はこんな感じでできます
// Widgetのビルド関数内の想定
final deviceInfo = ref.watch(deviceInfoProvider);
if (Platform.isAndroid) {
final androidInfo = device as AndroidDeviceInfo;
final osVersion = androidInfo.version.release!;
} else if (Platform.isIOS) {
final iosInfo = device as IosDeviceInfo;
final osVersion = iosInfo.systemVersion!
} else {
// それ以外
}
機種名を取得したい
これもdevice_info_plusで取得できます
// Android
final androidInfo = await deviceInfo.androidInfo;
final androidOsVersion = androidInfo.device!;
// iOS
final iosInfo = await deviceInfo.iosInfo;
final iosOsVersion = iosInfo.utsname.machine!;
最近、記事を書かれた@iseruuuuuさんの記事にもある通り、iOSの場合機種名を取得すると内部名での取得になります。
自分も内部名から一般名の変換に悩んでいたところ、@iseruuuuuさんの記事から名称を相互変換してくれるパッケージがあることを最近知りました(@iseruuuuuさん記事執筆ありがとうございます)
こんな感じで変換できます
final iosInfo = await deviceInfo.iosInfo;
final iosOsVersion = AppleProductName().lookup(iosInfo.utsname.machine!);
他Androidの使いそうな端末情報を取得したい
以下の情報もdevice_info_plusパッケージで取得できます
// Android
final androidInfo = await deviceInfo.androidInfo;
final sdkVersion = androidInfo.version.sdkInt!; // これはint
final brand = androidInfo.brand!; // 例 楽天、Google
(セマンティックバージョンニングでの)Version比較がしたい
versionパッケージが便利です
サンプルコードより
Version currentVersion = new Version(1, 0, 3);
Version latestVersion = Version.parse("2.1.0"); // 文字列からいい感じにパースしてくれるstaticメソッド
if (latestVersion > currentVersion) {
print("Update is available");
}
試し
以下コードで色々OS判定、情報取得、バージョン比較を実機で動かしてみました
環境
Flutter: 2.5.3(fvm使用)
version: 1.0.0+1
environment:
sdk: ">=2.14.0 <3.0.0"
dependencies:
apple_product_name: ^1.0.1
device_info_plus: ^3.2.1
flutter:
sdk: flutter
flutter_hooks: ^0.18.2
hooks_riverpod: ^1.0.1
package_info_plus: ^1.3.0
version: ^2.0.0
dev_dependencies:
flutter_test:
sdk: flutter
Android
アプリバージョンや端末情報列挙
ダイアログでOSバージョンの比較結果表示
iOS
アプリバージョンや端末情報列挙
ダイアログでOSバージョンの比較結果表示
iOSのシュミレーターは、iosInfo.utsname.machine
で機種名を取得した場合にその実行している機種名ではなくシュミレーター名になるので注意です
何か間違いや他の端末情報もよく取るだろうみたいな例があれば気軽にご連絡ください
Discussion