Migrate to 2.0
Update an app from movesense_plus 1.x, carp_movesense_flutter or mdsflutter to movesense_plus 2.0.
movesense_plus 2.0 is the plugin that was published as carp_movesense_flutter 0.1.x, renamed and extended with a typed device API. It replaces the 1.x releases of movesense_plus, which wrapped the mdsflutter plugin. Version 2.0 bundles the Movesense mobile library (MDS) for Android and iOS, so an app no longer adds the library itself.
What to change depends on the package that the app uses now:
| Package | What changes |
|---|---|
movesense_plus 1.x | The native setup and most of the API. See Migrate from 1.x. |
carp_movesense_flutter 0.1.x | The dependency, the imports and a few class names. See Migrate from carp_movesense_flutter. |
mdsflutter | The dependency, the import and the native setup. See Migrate from mdsflutter. |
Version 2.0 needs Dart 3.12 or later, which comes with Flutter 3.44 or later. It also needs Android minSdk 24 or later and iOS 15.0 or later. To configure Android and iOS, see Installation.
Migrate from 1.x
Raise the version constraint:
The update also removes mdsflutter, which 1.x brought along. If your code imports package:mdsflutter/Mds.dart, change that import as well. See Migrate from mdsflutter.
Remove the MDS setup
Version 1.x needed MDS in the app itself: the mdslib library on Android and the Movesense pod on iOS. Version 2.0 bundles both, so remove them.
On Android, delete the mdslib-<version>-release.aar file, usually in android/libs/. Then remove the flatDir repository that points to its folder:
In a Groovy android/build.gradle, the block reads flatDir { dirs "$rootDir/libs" }.
On iOS, remove the pod 'Movesense' line from ios/Podfile. The 1.x setup also replaced the use_frameworks! line of the Flutter template with static linkage and added use_modular_headers!. If you made these changes only for Movesense, undo them:
The plugin builds with the template's use_frameworks! and with Swift Package Manager.
Update the code
The API of version 2.0 is new. These are the most common changes:
| 1.x | 2.0 | |
|---|---|---|
| Scanning | Movesense().scan(), Movesense().devices | Movesense().startScan(), Movesense().scanResults |
MovesenseDevice constructor | Optional address, serial, name and deviceType | Required address, optional name and movesense; the properties are read-only |
connect() and disconnect() | Return void | Return Future<void>; follow statusEvents for the outcome |
canConnect() | Returns true when address is set | Removed, because address is required |
| Sensor streams | hr, ecg, imu, temperature and getStateEvents() are broadcast streams, empty when not connected | Single-subscription streams that emit a StateError when not connected |
| Connection status | DeviceConnectionStatus | MovesenseDeviceStatus |
| Battery level | DeviceBatteryLevel | MovesenseBatteryLevel |
| System state components | SystemStateComponent | MovesenseSystemState |
| Device types | MovesenseDeviceType.MD, HR_PLUS, HR2, FLASH | MovesenseDeviceType.md, hrPlus, hr2, flash |
MovesenseHR | average as int; rr is the first R-R interval of a notification | average as double, plus the full rrData list; rr is the last interval, or null when there is none |
MovesenseTemperature | measurement as int | measurement as double, plus a celsius getter |
MovesenseState | Extends MovesenseData, with an int timestamp | A standalone class with component and value, and an int? timestamp that is null for getState() reads |
| Device information | fromMovesenseData(String), fromMap(), toMap() and toJsonString(), and fromMap() and toMap() on MovesenseAddressInfo | fromMovesenseData(Map), fromJson() and toJson(), and fromJson() and toJson() on MovesenseAddressInfo |
| Data model constructors | Positional | Named, except the sample classes of MovesenseIMU, which keep positional (x, y, z) constructors with double instead of num values |
Scanning changes like this:
In 1.x, the scan stopped by itself after 60 seconds on iOS. In 2.0, it runs until you call stopScan(), or on iOS until you connect to a sensor.
Connecting and streaming change like this:
Read a sensor stream only after the status is connected: in version 2.0, a stream read before the sensor is connected emits a StateError.
Version 2.0 also fixes the inertial measurement unit (IMU) data. In 1.x, MovesenseIMU read the gyroscope and magnetometer samples from the accelerometer array, so both lists held accelerometer values.
IMU data from version 2.0 therefore differs from 1.x data. Do not use the gyroscope and magnetometer values of IMU data that the app recorded with 1.x.
Migrate from carp_movesense_flutter
pub.dev lists carp_movesense_flutter as discontinued and replaced by movesense_plus. Replace the dependency:
Not with carp_movesense_package 3.1.0
carp_movesense_package 3.1.0 depends on carp_movesense_flutter 0.1.x, which bundles MDS as a target named MovesenseMDS, as movesense_plus does. With Swift Package Manager, an iOS build of an app with these two plugins fails: "target names need to be unique across the package graph". Do not migrate an app that uses carp_movesense_package 3.1.0.
Change the imports and rename the client:
In 0.1.x, MovesenseDevice was the plain scan result class. That class is now MovesenseScanResult. The scanResults stream of Movesense now emits the typed MovesenseDevice, which still has name and address but no const constructor.
Update a custom platform
If the app has its own platform implementation, change its imports:
Then rename these classes:
| Name in 0.1.x | Name in 2.0 |
|---|---|
CarpMovesenseFlutterPlatform | MovesensePlatform |
PigeonCarpMovesenseFlutter | PigeonMovesense |
CarpMovesenseHostGateway, PigeonCarpMovesenseHostGateway | MovesenseHostGateway, PigeonMovesenseHostGateway |
MethodChannelCarpMovesenseFlutter | Removed; use PigeonMovesense |
The scanResults getter of the platform now emits MovesenseScanResult. For a fake platform that works with version 2.0, see Testing without a sensor.
Migrate from mdsflutter
Replace the dependency:
Change the import. Mds and MdsAsync have the same methods and signatures as in mdsflutter 2.3.1, so the calls compile unchanged:
mdsflutter needs the same MDS setup as 1.x. To remove it, see Remove the MDS setup.
These behaviors differ from mdsflutter:
- Scan duration: on iOS,
mdsflutterstops a scan after 60 seconds.movesense_plussets no time limit: a scan runs until you callMds.stopScan(), or on iOS until you connect to a sensor. - Scan errors:
Mds.startScan()andMdsAsync.startScan()take no error callback, so a scan error, such asBluetooth is not powered on.on iOS, becomes an unhandled exception. To handle scan errors, scan with aMovesenseclient and listen toscanResultswithonError. See Scan for sensors. - Connected sensors: on iOS, an
mdsflutterscan also reports sensors that are already connected to the iPhone. Amovesense_plusscan reports only sensors that advertise. - Connection callbacks: on Android,
Mds.connect()now callsonBleConnected;mdsfluttercalls it only on iOS. - Connecting again: on Android, you can call
Mds.connect()again after a sensor disconnects by itself.mdsflutterreportsAlready connected to <address>toonConnectionErrorinstead. - Subscriptions:
MdsAsync.subscribe()subscribes when you listen to the stream, not when you call it. - Error type:
MdsErrornow implementsException, so anon Exceptionclause catches it too; inmdsflutter, it is a plain class.
To scan for a set time, stop the scan in your code:
To handle failed requests, catch MdsError:
To replace the Mds calls with the typed device API, see Connecting a device.