酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Flutter で Riverpod を利用してデバイス名やデバイスのOSバージョンを取得する

Flutter でデバイス名やデバイスのOSバージョンを取得するためには device_info_plusapple_product_name を利用する。riverpod での利用を想定しており、本記事で紹介するサンプルコードでは FutureProvider を使っている 。

device_info_plus では iOSおよびmacOSの場合は iPhone15,2 などとモデル名を取得するため、パッとみてわかる一般名称に変換する apple_product_name をセットで導入している。ちなみに iPhone15,2 とは iPhone 14 Pro のモデル名である。

モデル名から一般名称に変換するパッケージは多数あるが、メンテナーが途中で更新を止めるケースが多く、数日前に更新のあった apple_product_name を使うことにした。

なお、Windows / Web / Linux に関しては調査できる環境がないため対象外としている。

デバイス名を取得する

デバイス名の取得には device_info_plus を利用している。前述のようにAppleデバイスはモデル名と商品名が異なるため apple_product_name を使って一般的な名称に変換するようにしている。apple_product_name の変換リストにモデル名がなかった場合例外を吐くためその対策もしている。

/// デバイスモデル
final deviceModelProvider = FutureProvider((ref) async {
  final deviceInfoPlugin = DeviceInfoPlugin();
  if (Platform.isAndroid) {
    final info = await deviceInfoPlugin.androidInfo;
    return info.model;
  } else if (Platform.isIOS) {
    final info = await deviceInfoPlugin.iosInfo;
    return info.utsname.productNameOrNull ?? info.utsname.machine;
  } else if (Platform.isMacOS) {
    final info = await deviceInfoPlugin.macOsInfo;
    return info.productNameOrNull ?? info.model;
  } else {
    return "unknown";
  }
});

apple_product_name を使いたくない場合は、device_info_plusにて取得した値をそのまま使えば返すようにすればよい。自前で変換リストを作るのもそんなに手間ではないと思う。

/// デバイスモデル
final deviceModelProvider = FutureProvider((ref) async {
  final deviceInfoPlugin = DeviceInfoPlugin();
  if (Platform.isAndroid) {
    final info = await deviceInfoPlugin.androidInfo;
    return info.model;
  } else if (Platform.isIOS) {
    final info = await deviceInfoPlugin.iosInfo;
    return info.utsname.machine;
  } else if (Platform.isMacOS) {
    final info = await deviceInfoPlugin.macOsInfo;
    return info.model;
  } else {
    return "unknown";
  }
});

ただしこの手のデータはメンテするのがものすごく大変なので素直に外部ライブラリを使わせてもらった方が良いだろう。

デバイスのOSバージョンを取得する

デバイスのOSバージョンも device_info_plus から取得できる。

/// デバイスのOSバージョン
final systemVersionProvider = FutureProvider((ref) async {
  final deviceInfoPlugin = DeviceInfoPlugin();
  if (Platform.isAndroid) {
    final info = await deviceInfoPlugin.androidInfo;
    return "Android ${info.version.release}";
  } else if (Platform.isIOS) {
    final info = await deviceInfoPlugin.iosInfo;
    return "${info.systemName} ${info.systemVersion}";
  } else if (Platform.isMacOS) {
    final info = await deviceInfoPlugin.macOsInfo;
    return "macOS ${info.osRelease}";
  } else {
    return "unknown";
  }
});

アプリバージョンを取得する

アプリ情報の取得には package_info_plus を使う。

/// アプリバージョン
final packageVersionProvider = FutureProvider((ref) async {
  final info = await PackageInfo.fromPlatform();
  return "${info.version} (${info.buildNumber})";
});

実行結果

上記の「デバイス名」「OSバージョン」「アプリバージョン」をどのように表示させるのか簡単なサンプルを紹介する。riverpod を使っている。

class SettingsScreen extends ConsumerWidget {
  const SettingsScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final packageVersion = ref.watch(packageVersionProvider).value ?? "unknown";
    final systemVersion = ref.watch(systemVersionProvider).value ?? "unknown";
    final deviceModel = ref.watch(deviceModelProvider).value ?? "unknown";

    return Scaffold(
      appBar: AppBar(
        title: const Text("タイトル"),
      ),
      body: Center(
        child: Column(
          children: [
            Text("アプリバージョン:$packageVersion"),
            Text("OSのバージョン:$systemVersion"),
            Text("デバイスモデル:$deviceModel"),
          ],
        ),
      ),
    );
  }
}

Android、iPhone 14 Pro、MacBook Pro での実行結果を下図に示す。

実行結果:左より Android、iPhone 14 Pro、MacBook Pro である。