📱

Flutterのsensors_plusライブラリを使ってみた

2024/03/28に公開

今回はFlutterのsensors_plusライブラリを使ってみるとのことです。

はじめに

流れは大体こんな感じです:

  1. プロジェクトを作成する
  2. ライブラリーを追加する
  3. コードを書く
  4. 実行する(途中はエラ〜が出たのでそれの修正)
  5. 楽しむ

プロジェクトを作成する

これはもうflutter createで作成するだけです。(Flutterの慣れた方は暗記しているかもしれないが僕は暗記していないです、理由は機会があれば改めて文章で書きます、 TODO 付けておく。。)

flutter create sensors_plus_sample

ライブラリーを追加する

pubspec.yamlに以下のコードに変更する(dependenciessensors_plus: ^5.0.0を入れる):

dependencies:
  sensors_plus: ^5.0.0

コードを書く

作ったWidgetを貼ります:

import 'package:flutter/material.dart';
import 'package:sensor_monitor/src/fps_checker.dart';
import 'package:sensor_monitor/src/max_last_second.dart';
import 'package:sensors_plus/sensors_plus.dart';

class SensorMiniMonitor extends StatefulWidget {
  const SensorMiniMonitor({Key? key}) : super(key: key);

  
  State<SensorMiniMonitor> createState() => _SensorMiniMonitorState();
}

class _SensorMiniMonitorState extends State<SensorMiniMonitor> {
  MaxLastSecond maxLastSecond = MaxLastSecond();

  FpsChecker fpsChecker = FpsChecker();
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('''
FPS: ${fpsChecker.fps}
x = ${maxLastSecond.xMax.toStringAsFixed(2)}
y = ${maxLastSecond.yMax.toStringAsFixed(2)}
z = ${maxLastSecond.zMax.toStringAsFixed(2)}
'''),
      ),
    );
  }

  
  void initState() {
    gyroscopeEventStream(samplingPeriod: SensorInterval.fastestInterval)
        .listen((event) {
      setState(() {
        fpsChecker.addFrame();
        maxLastSecond.update(DateTime.now(), event.x, event.y, event.z);
      });
    });
    super.initState();
  }
}

補足のクラスを貼ります:


class FpsChecker {
  final Queue<DateTime> _frames = Queue();

  int get fps => _frames.length;

  void addFrame() {
    final now = DateTime.now();
    _frames.add(now);
    while (_frames.first.isBefore(now.subtract(const Duration(seconds: 1)))) {
      _frames.removeFirst();
    }
  }
}

class MaxLastSecond {
  DateTime xMaxTime = DateTime.now();
  double xMax = 0.0;

  DateTime yMaxTime = DateTime.now();
  double yMax = 0.0;

  DateTime zMaxTime = DateTime.now();
  double zMax = 0.0;

  void update(DateTime time, double x, double y, double z) {
    if (x.abs() > xMax.abs()) {
      xMax = x;
      xMaxTime = time;
    }
    if (y.abs() > yMax.abs()) {
      yMax = y;
      yMaxTime = time;
    }
    if (z.abs() > zMax.abs()) {
      zMax = z;
      zMaxTime = time;
    }

    // remove old values
    final now = time;
    if (xMaxTime.isBefore(now.subtract(const Duration(seconds: 3)))) {
      xMax = x;
      xMaxTime = now;
    }
    if (yMaxTime.isBefore(now.subtract(const Duration(seconds: 3)))) {
      yMax = y;
      yMaxTime = now;
    }
    if (zMaxTime.isBefore(now.subtract(const Duration(seconds: 3)))) {
      zMax = z;
      zMaxTime = now;
    }
  }
}

Widgetだけを見れば使い方は分かるかと思いますが、gyroscopeEventStreamを使ってジャイロセンサーのデータを取得しています。
他にもaccelerometerEventStreamuserAccelerometerEventStreammagnetometerEventStreamがあります。

メリット

  • センサーのデータを取得するのが簡単
  • iOSのセンサーをAndroid側に合わせて計算してあるのでOS間の差異を気にしなくていい

iOSにビルドする時に発生した問題

iOS側ではios/Runner/GeneratedPluginRegistrant.mが生成されています、これはflutter pub getをすると自動で生成されます。しかしこの中にエラ〜が出てしまいました:

.../ios/Runner/GeneratedPluginRegistrant.m:10:9: Module 'sensors_plus' not found

ネットを調べると色々の解決策がありましたが、僕の場合はflutter build iosすることで解決しました。(ワイヤレスでビルドしているのでVSCodeでは力不足でXCodeを使ってビルドしています)

おわりに

Flutterのセンサーを取得するのは簡単です、sensors_plusライブラリを使うとOS間の差異を気にしなくていいので楽ですね。エラ〜があってもサクッと調べれば解決できてFlutter大好きです!!!

Discussion