chore(#695): vendor pristine flutter_blue_plus_android 8.2.2

Pristine import of pub.dev flutter_blue_plus_android-8.2.2 into
packages/, wired via dependency_overrides, mirroring the WinRT vendor
pattern from #686. FBP License v1.4 and BSD NOTICE retained.

Verified against the pub cache file-by-file: 9 of 12 files
byte-identical; AndroidManifest.xml, LICENSE and
FlutterBluePlusPlugin.java differ ONLY in end-of-line whitespace
(1, 4 and 11 lines respectively; the byte-perfect license text also
ships as LICENSE.md, which is byte-identical). No content changes;
verified with git diff --ignore-space-at-eol. Release APK builds
clean against the vendored copy before any patch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dev
Strycher 5 days ago committed by Benjamin Wiechel
parent ea08663d92
commit 3944895550

@ -0,0 +1,45 @@
## 8.2.2
* **[Release]** version bump for the flutter_blue_plus 2.2.2 release
## 8.2.1
* **[LICENSE]** clarifications to the development exemption
## 8.2.0
* **[LICENSE]** new tiers based on company size & development exemption
## 8.1.0
* **[LICENSE]** commercial license is now required for 15 or more employees
## 8.0.1
* Add License symlink
## 8.0.0
* Switch to FBP License
## 4.0.5
* Fixes to check for location services when plugin is called from a service
## 4.0.3
* Added option to disable Location Services check
## 4.0.2
* Fix compile error
## 4.0.1
* Fix compile error
## 4.0.0
* Use bytes instead of hex for platform communication (#1130)
* Check if Android location services are enabled when doing scan (#1167)
## 3.0.0
* Add option to provide pairing PIN to `createBond` (#1119)
## 2.0.1
* Add log color
## 2.0.0
* Replace void return types with bool return types
## 1.35.0
* Split from `flutter_blue_plus` as a federated implementation

@ -0,0 +1,77 @@
FlutterBluePlus License
Version 1.4
Copyright (c) 2026 Chip Weinberger
All rights reserved.
---
### Preamble (Non-Binding)
The intent of this license is to make FlutterBluePlus ("The Software") as free and open as possible for personal users, researchers, nonprofits, educational institutions, and hobbyists. For these users, the terms are similar to the BSD license: broad freedom to use, modify, and share.
For for-profit use and by for-profit organizations, a commercial license is required.
The revenue from commercial licenses supports the long-term maintenance and development of FlutterBluePlus.
This approach allows hobbyists, nonprofits, and educators to benefit from free and open software, while ensuring that for-profit companies who rely on it help sustain its future.
Please be aware that this project originated under the BSD-3 license, and some portions of the codebase remain under that license today. Compliance with those clauses is not required under the FlutterBluePlus License itself, but to remain fully compliant with the terms set by those contributors, it is advised that users continue to follow the BSD-3 conditions described in NOTICE.md. That relationship is between you and the BSD-licensed contributors.
This preamble is provided for explanation only and does not form part of the binding legal terms of this license.
---
### Section 1: Common Conditions (apply to all users)
Permission is hereby granted to any individual or organization to use, copy, modify, and distribute the Software in source code or binary form, subject to the following conditions:
**1. Source Code Redistributions.** Redistributions of source code must retain the above copyright notice and this entire license text without modification.
**2. Relicensing Prohibition.** The Software may not be relicensed under different terms by any party.
**3. Commercial Use Requirement.** Use of the Software by any for-profit organization requires a commercial license under Section 3, regardless of how the Software was obtained.
**4. Nonprofit & Educational Exemption.** Registered nonprofit organizations and accredited educational institutions are exempt from this requirement and may use the Software under Section 2.
---
### Section 2: Open Use Terms (for nonprofits, educational institutions, personal use)
Use of the Software is free of charge for any registered nonprofit organization, accredited educational institution, or personal user, subject to the Common Conditions and the following additional terms:
**1. Endorsement Restriction.** Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission.
---
### Section 3: Commercial Terms (for for-profit organizations)
Any use of FlutterBluePlus by or for a for-profit company or corporation — including commercial use by individuals — requires the purchase of a commercial license, subject to the Common Conditions and the following additional terms:
**1. License Fee.** Commercial licenses are offered in the following tiers, based on employee count **at the time of purchase**. The associated cost is listed on the official FlutterBluePlus payment portal.
- **Starter:** 0–9 employees
- **Team:** 10–29 employees
- **Business:** 30–99 employees
- **Enterprise:** 100 or more employees
**2. Perpetual Use.** The license grants perpetual rights to use the Software and to receive all current and future software updates made available by the licensor after purchase.
**3. Development Clarification.** Use of the Software during development, testing, or evaluation by a for-profit organization is considered commercial use and requires a commercial license.
**4. Official Payment Portal.** Payment must be made via the official payment portal: https://jamcorder.myshopify.com/products/flutterblueplus-commercial-license
**5. Validity of Offer.** This Section constitutes an offer only while this license version is the current version published in the main branch of the official FlutterBluePlus repository. Once superseded, replaced, or withdrawn, this version shall no longer be considered an active offer, even if archived copies remain publicly visible.
A valid commercial license covers use of all current and future packages that
are part of the FlutterBluePlus project, including its federated packages
(e.g., flutter_blue_plus, flutter_blue_plus_darwin, flutter_blue_plus_android,
flutter_blue_plus_web, flutter_blue_plus_linux, flutter_blue_plus_platform_interface).
Only a single commercial license is required per organization, regardless of how many
FlutterBluePlus packages are used.
---
### Section 4: Warranty Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,77 @@
FlutterBluePlus License
Version 1.4
Copyright (c) 2026 Chip Weinberger
All rights reserved.
---
### Preamble (Non-Binding)
The intent of this license is to make FlutterBluePlus ("The Software") as free and open as possible for personal users, researchers, nonprofits, educational institutions, and hobbyists. For these users, the terms are similar to the BSD license: broad freedom to use, modify, and share.
For for-profit use and by for-profit organizations, a commercial license is required.
The revenue from commercial licenses supports the long-term maintenance and development of FlutterBluePlus.
This approach allows hobbyists, nonprofits, and educators to benefit from free and open software, while ensuring that for-profit companies who rely on it help sustain its future.
Please be aware that this project originated under the BSD-3 license, and some portions of the codebase remain under that license today. Compliance with those clauses is not required under the FlutterBluePlus License itself, but to remain fully compliant with the terms set by those contributors, it is advised that users continue to follow the BSD-3 conditions described in NOTICE.md. That relationship is between you and the BSD-licensed contributors.
This preamble is provided for explanation only and does not form part of the binding legal terms of this license.
---
### Section 1: Common Conditions (apply to all users)
Permission is hereby granted to any individual or organization to use, copy, modify, and distribute the Software in source code or binary form, subject to the following conditions:
**1. Source Code Redistributions.** Redistributions of source code must retain the above copyright notice and this entire license text without modification.
**2. Relicensing Prohibition.** The Software may not be relicensed under different terms by any party.
**3. Commercial Use Requirement.** Use of the Software by any for-profit organization requires a commercial license under Section 3, regardless of how the Software was obtained.
**4. Nonprofit & Educational Exemption.** Registered nonprofit organizations and accredited educational institutions are exempt from this requirement and may use the Software under Section 2.
---
### Section 2: Open Use Terms (for nonprofits, educational institutions, personal use)
Use of the Software is free of charge for any registered nonprofit organization, accredited educational institution, or personal user, subject to the Common Conditions and the following additional terms:
**1. Endorsement Restriction.** Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission.
---
### Section 3: Commercial Terms (for for-profit organizations)
Any use of FlutterBluePlus by or for a for-profit company or corporation — including commercial use by individuals — requires the purchase of a commercial license, subject to the Common Conditions and the following additional terms:
**1. License Fee.** Commercial licenses are offered in the following tiers, based on employee count **at the time of purchase**. The associated cost is listed on the official FlutterBluePlus payment portal.
- **Starter:** 0–9 employees
- **Team:** 10–29 employees
- **Business:** 30–99 employees
- **Enterprise:** 100 or more employees
**2. Perpetual Use.** The license grants perpetual rights to use the Software and to receive all current and future software updates made available by the licensor after purchase.
**3. Development Clarification.** Use of the Software during development, testing, or evaluation by a for-profit organization is considered commercial use and requires a commercial license.
**4. Official Payment Portal.** Payment must be made via the official payment portal: https://jamcorder.myshopify.com/products/flutterblueplus-commercial-license
**5. Validity of Offer.** This Section constitutes an offer only while this license version is the current version published in the main branch of the official FlutterBluePlus repository. Once superseded, replaced, or withdrawn, this version shall no longer be considered an active offer, even if archived copies remain publicly visible.
A valid commercial license covers use of all current and future packages that
are part of the FlutterBluePlus project, including its federated packages
(e.g., flutter_blue_plus, flutter_blue_plus_darwin, flutter_blue_plus_android,
flutter_blue_plus_web, flutter_blue_plus_linux, flutter_blue_plus_platform_interface).
Only a single commercial license is required per organization, regardless of how many
FlutterBluePlus packages are used.
---
### Section 4: Warranty Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,39 @@
To comply with the requirements of the original BSD-style license,
the full text of that license is reproduced below. It applies to all
releases of this project up to and including version 1.36.8, published
before October 2025. Those releases remain available under the terms
below, which are irrevocable.
All releases beginning with version 2.0.0, published in October 2025
and onward, are licensed under the FlutterBluePlus License.
------
Copyright 2017-2024, Paul DeMarco, Bosko Popovic, Charles Weinberger, Thomas Clark.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Buffalo PC Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,15 @@
# flutter_blue_plus_android
The Android implementation of [`flutter_blue_plus`][1].
## Usage
This package is [endorsed][2], which means you can simply use `flutter_blue_plus`
normally. This package will be automatically included in your app when you do,
so you do not need to add it to your `pubspec.yaml`.
However, if you `import` this package to use any of its APIs directly, you
should add it to your `pubspec.yaml` as usual.
[1]: https://pub.dev/packages/flutter_blue_plus
[2]: https://flutter.dev/to/endorsed-federated-plugin

@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/tools/linter-rules.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/tools/analysis

@ -0,0 +1,33 @@
group 'com.lib.flutter_blue_plus'
version '1.0'
apply plugin: 'com.android.library'
android {
compileSdkVersion = flutter.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
lintOptions {
abortOnError false
}
defaultConfig {
minSdkVersion 21
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
options.compilerArgs << "-Xlint:unchecked"
}
}
// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'com.lib.flutter_blue_plus'
}
}

@ -0,0 +1 @@
rootProject.name = 'flutter_blue_plus'

@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lib.flutter_blue_plus">
<!-- This file must be here to fix build errors in Flutter V2 -->
<!-- But we intentionally leave this blank because android bluetooth permissions are
complicated and always changing. By leaving this blank, users can set exactly the
permissions they want, without having to 'undo' the permissions we set here -->
</manifest>

@ -0,0 +1,583 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_blue_plus_platform_interface/flutter_blue_plus_platform_interface.dart';
final class FlutterBluePlusAndroid extends FlutterBluePlusPlatform {
@visibleForTesting
final methodChannel = const MethodChannel('flutter_blue_plus/methods');
var _didRestart = false;
var _logLevel = LogLevel.none;
var _logColor = true;
final _onAdapterStateChangedController = StreamController<BmBluetoothAdapterState>.broadcast();
final _onBondStateChangedController = StreamController<BmBondStateResponse>.broadcast();
final _onCharacteristicReceivedController = StreamController<BmCharacteristicData>.broadcast();
final _onCharacteristicWrittenController = StreamController<BmCharacteristicData>.broadcast();
final _onConnectionStateChangedController = StreamController<BmConnectionStateResponse>.broadcast();
final _onDescriptorReadController = StreamController<BmDescriptorData>.broadcast();
final _onDescriptorWrittenController = StreamController<BmDescriptorData>.broadcast();
final _onDetachedFromEngineController = StreamController<BmDetachedFromEngineResponse>.broadcast();
final _onDiscoveredServicesController = StreamController<BmDiscoverServicesResult>.broadcast();
final _onMtuChangedController = StreamController<BmMtuChangedResponse>.broadcast();
final _onNameChangedController = StreamController<BmNameChanged>.broadcast();
final _onReadRssiController = StreamController<BmReadRssiResult>.broadcast();
final _onScanResponseController = StreamController<BmScanResponse>.broadcast();
final _onServicesResetController = StreamController<BmBluetoothDevice>.broadcast();
final _onTurnOnResponseController = StreamController<BmTurnOnResponse>.broadcast();
@override
Stream<BmBluetoothAdapterState> get onAdapterStateChanged {
return _onAdapterStateChangedController.stream;
}
@override
Stream<BmBondStateResponse> get onBondStateChanged {
return _onBondStateChangedController.stream;
}
@override
Stream<BmCharacteristicData> get onCharacteristicReceived {
return _onCharacteristicReceivedController.stream;
}
@override
Stream<BmCharacteristicData> get onCharacteristicWritten {
return _onCharacteristicWrittenController.stream;
}
@override
Stream<BmConnectionStateResponse> get onConnectionStateChanged {
return _onConnectionStateChangedController.stream;
}
@override
Stream<BmDescriptorData> get onDescriptorRead {
return _onDescriptorReadController.stream;
}
@override
Stream<BmDescriptorData> get onDescriptorWritten {
return _onDescriptorWrittenController.stream;
}
@override
Stream<BmDetachedFromEngineResponse> get onDetachedFromEngine {
return _onDetachedFromEngineController.stream;
}
@override
Stream<BmDiscoverServicesResult> get onDiscoveredServices {
return _onDiscoveredServicesController.stream;
}
@override
Stream<BmMtuChangedResponse> get onMtuChanged {
return _onMtuChangedController.stream;
}
@override
Stream<BmNameChanged> get onNameChanged {
return _onNameChangedController.stream;
}
@override
Stream<BmReadRssiResult> get onReadRssi {
return _onReadRssiController.stream;
}
@override
Stream<BmScanResponse> get onScanResponse {
return _onScanResponseController.stream;
}
@override
Stream<BmBluetoothDevice> get onServicesReset {
return _onServicesResetController.stream;
}
@override
Stream<BmTurnOnResponse> get onTurnOnResponse {
return _onTurnOnResponseController.stream;
}
static void registerWith() {
FlutterBluePlusPlatform.instance = FlutterBluePlusAndroid();
}
@override
Future<bool> clearGattCache(
BmClearGattCacheRequest request,
) async {
return await _callAndroidMethod<bool>(
'clearGattCache',
request.remoteId.str,
) ==
true;
}
@override
Future<bool> connect(
BmConnectRequest request,
) async {
return await _callAndroidMethod<bool>(
'connect',
request.toMap(),
) ==
true;
}
@override
Future<bool> createBond(
BmCreateBondRequest request,
) async {
return await _callAndroidMethod<bool>(
'createBond',
request.toMap(),
) ==
true;
}
@override
Future<bool> disconnect(
BmDisconnectRequest request,
) async {
return await _callAndroidMethod<bool>(
'disconnect',
request.remoteId.str,
) ==
true;
}
@override
Future<bool> discoverServices(
BmDiscoverServicesRequest request,
) async {
return await _callAndroidMethod<bool>(
'discoverServices',
request.remoteId.str,
) ==
true;
}
@override
Future<BmBluetoothAdapterName> getAdapterName(
BmBluetoothAdapterNameRequest request,
) async {
return BmBluetoothAdapterName(
adapterName: await _callAndroidMethod(
'getAdapterName',
),
);
}
@override
Future<BmBluetoothAdapterState> getAdapterState(
BmBluetoothAdapterStateRequest request,
) async {
return BmBluetoothAdapterState.fromMap(
await _callAndroidMethod(
'getAdapterState',
),
);
}
@override
Future<BmBondStateResponse> getBondState(
BmBondStateRequest request,
) async {
return BmBondStateResponse.fromMap(
await _callAndroidMethod(
'getBondState',
request.remoteId.str,
),
);
}
@override
Future<BmDevicesList> getBondedDevices(
BmBondedDevicesRequest request,
) async {
return BmDevicesList.fromMap(
await _callAndroidMethod(
'getBondedDevices',
),
);
}
@override
Future<PhySupport> getPhySupport(
PhySupportRequest request,
) async {
return PhySupport.fromMap(
await _callAndroidMethod(
'getPhySupport',
),
);
}
@override
Future<BmDevicesList> getSystemDevices(
BmSystemDevicesRequest request,
) async {
return BmDevicesList.fromMap(
await _callAndroidMethod(
'getSystemDevices',
),
);
}
@override
Future<bool> isSupported(
BmIsSupportedRequest request,
) async {
return await _callAndroidMethod<bool>(
'isSupported',
) ==
true;
}
@override
Future<bool> readCharacteristic(
BmReadCharacteristicRequest request,
) async {
return await _callAndroidMethod<bool>(
'readCharacteristic',
request.toMap(),
) ==
true;
}
@override
Future<bool> readDescriptor(
BmReadDescriptorRequest request,
) async {
return await _callAndroidMethod<bool>(
'readDescriptor',
request.toMap(),
) ==
true;
}
@override
Future<bool> readRssi(
BmReadRssiRequest request,
) async {
return await _callAndroidMethod<bool>(
'readRssi',
request.remoteId.str,
) ==
true;
}
@override
Future<bool> removeBond(
BmRemoveBondRequest request,
) async {
return await _callAndroidMethod<bool>(
'removeBond',
request.remoteId.str,
) ==
true;
}
@override
Future<bool> requestConnectionPriority(
BmConnectionPriorityRequest request,
) async {
return await _callAndroidMethod<bool>(
'requestConnectionPriority',
request.toMap(),
) ==
true;
}
@override
Future<bool> requestMtu(
BmMtuChangeRequest request,
) async {
return await _callAndroidMethod<bool>(
'requestMtu',
request.toMap(),
) ==
true;
}
@override
Future<bool> setLogLevel(
BmSetLogLevelRequest request,
) async {
_logLevel = request.logLevel;
_logColor = request.logColor;
return await _callAndroidMethod<bool>(
'setLogLevel',
request.logLevel.index,
) ==
true;
}
@override
Future<bool> setNotifyValue(
BmSetNotifyValueRequest request,
) async {
return await _callAndroidMethod<bool>(
'setNotifyValue',
request.toMap(),
) ==
true;
}
@override
Future<bool> setOptions(
BmSetOptionsRequest request,
) async {
return await _callAndroidMethod<bool>(
'setOptions',
request.toMap(),
) ==
true;
}
@override
Future<bool> setPreferredPhy(
BmPreferredPhy request,
) async {
return await _callAndroidMethod<bool>(
'setPreferredPhy',
request.toMap(),
) ==
true;
}
@override
Future<bool> startScan(
BmScanSettings request,
) async {
return await _callAndroidMethod<bool>(
'startScan',
request.toMap(),
) ==
true;
}
@override
Future<bool> stopScan(
BmStopScanRequest request,
) async {
return await _callAndroidMethod<bool>(
'stopScan',
) ==
true;
}
@override
Future<bool> turnOff(
BmTurnOffRequest request,
) async {
return await _callAndroidMethod<bool>(
'turnOff',
) ==
true;
}
@override
Future<bool> turnOn(
BmTurnOnRequest request,
) async {
return await _callAndroidMethod<bool>(
'turnOn',
) ==
true;
}
@override
Future<bool> writeCharacteristic(
BmWriteCharacteristicRequest request,
) async {
return await _callAndroidMethod<bool>(
'writeCharacteristic',
request.toMap(),
) ==
true;
}
@override
Future<bool> writeDescriptor(
BmWriteDescriptorRequest request,
) async {
return await _callAndroidMethod<bool>(
'writeDescriptor',
request.toMap(),
) ==
true;
}
Future<T?> _callAndroidMethod<T>(
String method, [
dynamic arguments,
]) async {
// restart platform
if (!_didRestart && method != "setLogLevel") {
await _flutterRestart();
}
// set platform method handler
methodChannel.setMethodCallHandler(_methodCallHandler);
// log args
if (_logLevel == LogLevel.verbose) {
var func = '<$method>';
var args = arguments.toString();
func = _logColor ? '\x1B[1;30m$func\x1B[0m' : func;
args = _logColor ? '\x1B[1;35m$args\x1B[0m' : args;
FlutterBluePlusPlatform.log('[FBP] $func args: $args');
}
// invoke
final out = await methodChannel.invokeMethod<T>(method, arguments);
// log result
if (_logLevel == LogLevel.verbose) {
var func = '($method)';
var result = out.toString();
func = _logColor ? '\x1B[1;30m$func\x1B[0m' : func;
result = _logColor ? '\x1B[1;33m$result\x1B[0m' : result;
FlutterBluePlusPlatform.log('[FBP] $func result: $result');
}
return out;
}
Future<void> _flutterRestart() async {
// wait for all devices to disconnect
if ((await methodChannel.invokeMethod('flutterRestart')) != 0) {
await Future.delayed(Duration(milliseconds: 50));
while ((await methodChannel.invokeMethod('connectedCount')) != 0) {
await Future.delayed(Duration(milliseconds: 50));
}
}
_didRestart = true;
}
Future<void> _methodCallHandler(
MethodCall call,
) async {
// log result
if (_logLevel == LogLevel.verbose) {
var func = '[[ ${call.method} ]]';
var result = switch (call.method) {
'OnDiscoveredServices' => _prettyPrint(call.arguments),
_ => call.arguments.toString(),
};
func = _logColor ? '\x1B[1;30m$func\x1B[0m' : func;
result = _logColor ? '\x1B[1;33m$result\x1B[0m' : result;
FlutterBluePlusPlatform.log('[FBP] $func result: $result');
}
// handle method call
switch (call.method) {
case 'OnAdapterStateChanged':
return _onAdapterStateChangedController.add(
BmBluetoothAdapterState.fromMap(
call.arguments,
),
);
case 'OnBondStateChanged':
return _onBondStateChangedController.add(
BmBondStateResponse.fromMap(
call.arguments,
),
);
case 'OnCharacteristicReceived':
return _onCharacteristicReceivedController.add(
BmCharacteristicData.fromMap(
call.arguments,
),
);
case 'OnCharacteristicWritten':
return _onCharacteristicWrittenController.add(
BmCharacteristicData.fromMap(
call.arguments,
),
);
case 'OnConnectionStateChanged':
return _onConnectionStateChangedController.add(
BmConnectionStateResponse.fromMap(
call.arguments,
),
);
case 'OnDescriptorRead':
return _onDescriptorReadController.add(
BmDescriptorData.fromMap(
call.arguments,
),
);
case 'OnDescriptorWritten':
return _onDescriptorWrittenController.add(
BmDescriptorData.fromMap(
call.arguments,
),
);
case 'OnDetachedFromEngine':
return _onDetachedFromEngineController.add(
BmDetachedFromEngineResponse(),
);
case 'OnDiscoveredServices':
return _onDiscoveredServicesController.add(
BmDiscoverServicesResult.fromMap(
call.arguments,
),
);
case 'OnMtuChanged':
return _onMtuChangedController.add(
BmMtuChangedResponse.fromMap(
call.arguments,
),
);
case 'OnNameChanged':
return _onNameChangedController.add(
BmNameChanged.fromMap(
call.arguments,
),
);
case 'OnReadRssi':
return _onReadRssiController.add(
BmReadRssiResult.fromMap(
call.arguments,
),
);
case 'OnScanResponse':
return _onScanResponseController.add(
BmScanResponse.fromMap(
call.arguments,
),
);
case 'OnServicesReset':
return _onServicesResetController.add(
BmBluetoothDevice.fromMap(
call.arguments,
),
);
case 'OnTurnOnResponse':
return _onTurnOnResponseController.add(
BmTurnOnResponse.fromMap(
call.arguments,
),
);
}
}
String _prettyPrint(
dynamic data,
) {
if (data is Map || data is List) {
return JsonEncoder.withIndent(' ').convert(data);
} else {
return data.toString();
}
}
}

@ -0,0 +1,27 @@
name: flutter_blue_plus_android
description: Android implementation of the flutter_blue_plus plugin.
version: 8.2.2
homepage: https://github.com/chipweinberger/flutter_blue_plus
environment:
sdk: ^3.0.0
flutter: '>=3.7.0'
dependencies:
flutter:
sdk: flutter
flutter_blue_plus_platform_interface: 8.2.2
dev_dependencies:
flutter_lints: ^5.0.0
flutter_test:
sdk: flutter
flutter:
plugin:
implements: flutter_blue_plus
platforms:
android:
package: com.lib.flutter_blue_plus
pluginClass: FlutterBluePlusPlugin
dartPluginClass: FlutterBluePlusAndroid

@ -440,12 +440,11 @@ packages:
source: hosted
version: "2.2.3"
flutter_blue_plus_android:
dependency: transitive
dependency: "direct overridden"
description:
name: flutter_blue_plus_android
sha256: d66bdcb0438e643d5de4af914851bdf7322448384795666efe92236626484740
url: "https://pub.dev"
source: hosted
path: "packages/flutter_blue_plus_android"
relative: true
source: path
version: "8.2.2"
flutter_blue_plus_darwin:
dependency: transitive

@ -98,6 +98,14 @@ hooks:
android-x64:
backends: [cpu]
# Vendored copy of the endorsed Android implementation, patched to close
# leaked BluetoothGatt handles (#694). Pristine 8.2.2 import first; the
# patch rides on top as its own commit for reviewability, like the WinRT
# vendor on #686.
dependency_overrides:
flutter_blue_plus_android:
path: packages/flutter_blue_plus_android
dev_dependencies:
flutter_test:
sdk: flutter

Loading…
Cancel
Save

Powered by TurnKey Linux.