flutter_bactrack 0.4.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 50

BACtrack Plugin #

A Flutter plugin that wraps the BACtrack SDK for both iOS and Android. This plugin will allow you to collect breathalyzer samples from a BACtrack Bluetooth breathalyzer.

BACtrack Screen Shot


The following features of the BACtrack SDK are supported at this time by the plugin.

  • ✅ Support for connecting to nearest breathalyzer (with or without a timeout)
  • ✅ Mannually disconnect from the breathalyzer
  • ✅ Take a BAC reading from the breathalyzer including the countdown, blowing, analysis, and results phases.
  • ✅ Get battery voltage level of breathalyzer
  • ✅ Permissions are automatically managed by the plugin

⚠️ Note: this plugin is written in Kotlin and Swift.

Getting Started #

You are required to obtain an API key in order to use the BACtrack SDK to connect to a BACtrack breathalyzer. API keys are freely available by registering on the BACtrack developer site.


The following permissions must be declared in the manifest section of your application's manifest file in order to use the BACtrack SDK.


    <!-- ... -->

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


On iOS, you only need to declare the Bluetooth permission in your Info.plist file in order to use the BACtrack SDK.

    <!-- ... -->
    <string>This application needs access to Bluetooth for breathalyzer readings</string>
    <!-- ... -->


The first thing to do is to get an instance of the plugin.

try {
  final apiKey = insertYourApiKeyHere;
  _plugin = await FlutterBactrack.instance(apiKey);
  // Init succeeded!
} on PlatformException catch (e) {
  // Init failed!

Note: If you are concerned about the security of your API key, you may want to retrieve it from your server rather than put it in your source code. Once you have received it from your server, you can easily store it securely on your device for future runs using the flutter_secure_storage plugin.

BACtrack Status Notifications

The BACtrack SDK is designed to return all notifications through a callback interface. For Flutter, this has been abstracted to a Dart Stream. The plugin's statusStream will return all of the notifications from the SDK in the form of a BACtrackStatus object. This object wraps a BACtrackState enum that identifies the callback that was invoked as well as a message String containing the argument, if any, that was passed to the native callback function. Check the API documentation for a list of which states contain messages.

Taking a Breathalyzer Sample

The following code will connect to the nearest breathalyzer and start a sample collection once it has received the BACtrackState.connected state.

try {
    .where((BACtrackStatus status) => status.state == BACtrackState.connected)
      (BACtrackStatus status) {
         _plugin.startCountdown().then((bool result) => /* true if success in starting countdowwn */);

} on PlatformException catch (e) {
  // errors reported here

The above code sets up a listener on the plugin's statusStream that filters out everything except the connected message. Then it calls the plugin to connect to the nearest breathalyzer. Once the connected status shows up on the statusStream, the plugin's startCountdown method is called to begin the process of taking a BAC sample.

That example is a bit simplistic. In reality you would want to listen for more of the status updates that can be emitted by the statusStream in response to a connectToNearestBreathalyer() call. For example, any of the following status states maybe be emitted when you connect to a breathalyzer:

  • BACtrackState.apiKeyAuthorized
  • BACtrackState.apiKeyDeclined
  • BACtrackState.didConnect
  • BACtrackState.connected
  • BACtrackState.connectionTimeout

Check the API documentation for details on which status updates can be emitted in response to each of the plugin's method calls.

⚠️ Note: It is possible to receive a BACtrackState.disconnected status at any time after you have received a BACtrackState.connected status.

Future Work #

The plugin does not currently support manual scanning for breathalyzers so that you can manually choose which one to connect. This functionality is planned for a future release of the plugin.

Getting Help #

If you have any questions or problems with the plugin, please file an issue at the GitHub repository. I don't work on this full time, but I'll try to offer whatever help I can.

🐞 🐜 PRs are welcome! 🐝 🐛

v0.4.1 #

  • Documentation improvements

v0.4.0 #

  • Fix for permissions problems with apps that use the old plugin system.
  • Documentation improvements

v0.3.1 #

  • Documentation improvements

v0.3.0 #

  • FlutterBactrack constructor should have been private.
  • Documentation improvements

v0.2.0 #

  • Small improvements to API
  • Documentation improvements

v0.1.0 #

  • Supports basic functionality on Android and iOS
  • Uses BACtrack SDK to provide
    • Support for connecting to nearest breathalyzer
    • Get battery voltage level of breathalyzer
    • Take a BAC reading from the breathalyzer


import 'package:flutter/material.dart';
import 'package:flutter_bactrack_example/api_key_page.dart';
import 'package:flutter_bactrack_example/connection_page.dart';
import 'package:flutter_bactrack_example/control_page.dart';

void main() => runApp(BACtrackExampleApp());

class BACtrackExampleApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateRoute: routeGenerator,

final appBar = AppBar(title: Text("BACtrack Plugin Example"));

const homeRoute = '/';
const connectRoute = '/connect';
const controlRoute = '/control';

MaterialPageRoute routeGenerator(settings) {
  switch (settings.name) {
    case connectRoute:
      return MaterialPageRoute(builder: (context) {
        return ConnectionPage(apiKey: settings.arguments);

    case controlRoute:
      return MaterialPageRoute(builder: (context) {
        return ControlPage(bacTrackPlugin: settings.arguments);

      return MaterialPageRoute(builder: (_) => ApiKeyPage());

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  flutter_bactrack: ^0.4.1

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:flutter_bactrack/flutter_bactrack.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Jul 9, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.13
  • Flutter: 1.17.5

Analysis suggestions

Package does not support Flutter platform linux

Because of import path [package:flutter_bactrack/flutter_bactrack.dart] that declares support for platforms: android, ios

Package does not support Flutter platform macos

Because of import path [package:flutter_bactrack/flutter_bactrack.dart] that declares support for platforms: android, ios

Package does not support Flutter platform web

Because of import path [package:flutter_bactrack/flutter_bactrack.dart] that declares support for platforms: android, ios

Package does not support Flutter platform windows

Because of import path [package:flutter_bactrack/flutter_bactrack.dart] that declares support for platforms: android, ios

Package not compatible with SDK dart

because of import path [flutter_bactrack] that is in a package requiring null.

Health suggestions

Format lib/flutter_bactrack.dart.

Run flutter format to format lib/flutter_bactrack.dart.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.1
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies