-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ee30251
commit cc1fac9
Showing
51 changed files
with
2,443 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Miscellaneous | ||
*.class | ||
*.log | ||
*.pyc | ||
*.swp | ||
.DS_Store | ||
.atom/ | ||
.buildlog/ | ||
.history | ||
.svn/ | ||
migrate_working_dir/ | ||
|
||
# IntelliJ related | ||
*.iml | ||
*.ipr | ||
*.iws | ||
.idea/ | ||
|
||
# The .vscode folder contains launch configuration and tasks you configure in | ||
# VS Code which you may wish to be included in version control, so this line | ||
# is commented out by default. | ||
#.vscode/ | ||
|
||
# Flutter/Dart/Pub related | ||
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. | ||
/pubspec.lock | ||
**/doc/api/ | ||
.dart_tool/ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# This file tracks properties of this Flutter project. | ||
# Used by Flutter tool to assess capabilities and perform upgrades etc. | ||
# | ||
# This file should be version controlled and should not be manually edited. | ||
|
||
version: | ||
revision: "300451adae589accbece3490f4396f10bdf15e6e" | ||
channel: "stable" | ||
|
||
project_type: plugin | ||
|
||
# Tracks metadata for the flutter migrate command | ||
migration: | ||
platforms: | ||
- platform: root | ||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e | ||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e | ||
- platform: android | ||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e | ||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e | ||
|
||
# User provided section | ||
|
||
# List of Local paths (relative to this file) that should be | ||
# ignored by the migrate tool. | ||
# | ||
# Files that are not part of the templates will be ignored by default. | ||
unmanaged_files: | ||
- 'lib/main.dart' | ||
- 'ios/Runner.xcodeproj/project.pbxproj' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 0.0.1 | ||
|
||
* Initial release: Scan for and connect to BL Classic devices. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
# flutter_blue_classic | ||
|
||
Flutter_blue_classic is a flutter plugin for communicating with bluetooth classic devices. | ||
If you want to use an Bluetooth low energy (BLE) device, you might want to | ||
consider [flutter_blue_plus](https://pub.dev/packages/flutter_blue_plus). | ||
|
||
<!-- TOC --> | ||
* [flutter_blue_classic](#flutterblueclassic) | ||
* [A note on iOS](#a-note-on-ios) | ||
* [Getting Started](#getting-started) | ||
* [minSdkVersion](#minsdkversion) | ||
* [Permissions](#permissions) | ||
* [Without location access](#without-location-access) | ||
* [With location access](#with-location-access) | ||
* [Reference](#reference) | ||
* [FlutterBlueClassic](#flutterblueclassic-1) | ||
* [BluetoothConnection](#bluetoothconnection) | ||
* [Acknowledgement](#acknowledgement) | ||
<!-- TOC --> | ||
|
||
## A note on iOS | ||
|
||
This plugin is currently only compatible with Android. iOS does not provide a similar interface for | ||
Bluetooth Classic like Android. On iOS your BL device must | ||
be [MFi (Made for iPod/iPhone)](https://mfi.apple.com/en/faqs) | ||
certified and you will have to use | ||
the [External Accessory Framework](https://developer.apple.com/documentation/externalaccessory/). | ||
Since this is out of the scope of this package, you will have to implement this yourself. | ||
|
||
## Getting Started | ||
|
||
### minSdkVersion | ||
|
||
This package is only compatible with Android SDK 21 or higher. Please set your minSdkVersion in the | ||
android/app/build.gradle accordingly. | ||
|
||
### Permissions | ||
|
||
As the Android permission requirements can differ from case to case, this package does not define | ||
any | ||
permissions in it's Manifest. It is therefore necessary to declare them yourself. For detailed | ||
information, take a look at | ||
the [Android Developer Documentation on Permissions](https://developer.android.com/develop/connectivity/bluetooth/bt-permissions). | ||
|
||
Below are two common presets: | ||
|
||
#### Without location access | ||
|
||
In the **android/app/src/main/AndroidManifest.xml** add: | ||
|
||
```xml | ||
<!-- Permissions for Android 12 or above --> | ||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" | ||
android:usesPermissionFlags="neverForLocation" /><uses-permission | ||
android:name="android.permission.BLUETOOTH_CONNECT" /> | ||
|
||
<!-- legacy for Android 11 or lower --> | ||
<uses-permission android:name="android.permission.BLUETOOTH" | ||
android:maxSdkVersion="30" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" | ||
android:maxSdkVersion="30" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" | ||
android:maxSdkVersion="30" /> | ||
|
||
<!-- legacy for Android 9 or lower --> | ||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" | ||
android:maxSdkVersion="28" /> | ||
``` | ||
|
||
#### With location access | ||
|
||
In the **android/app/src/main/AndroidManifest.xml** add: | ||
|
||
```xml | ||
<!-- Permissions for Android 12 or above --> | ||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /><uses-permission | ||
android:name="android.permission.BLUETOOTH_CONNECT" /><uses-permission | ||
android:name="android.permission.ACCESS_FINE_LOCATION" /> | ||
|
||
<!-- legacy for Android 11 or lower --> | ||
<uses-permission android:name="android.permission.BLUETOOTH" | ||
android:maxSdkVersion="30" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" | ||
android:maxSdkVersion="30" /> | ||
|
||
<!-- legacy for Android 9 or lower --> | ||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" | ||
android:maxSdkVersion="28" /> | ||
``` | ||
|
||
Then pass the `accessFineLocation` parameter when initializing the plugin: | ||
|
||
```dart | ||
final blueClassic = FlutterBlueClassic(usesFineLocation: true); | ||
``` | ||
|
||
## Reference | ||
|
||
### FlutterBlueClassic | ||
| | Description | | ||
|:----------------|:-------------------------------------------------------------------| | ||
| isSupported | Checks whether the device supports Bluetooth | | ||
| isEnabled | Checks whether Bluetooth is enabled | | ||
| adapterStateNow | Current state of the bluetooth adapter | | ||
| adapterState | Stream of on, off and intermediary states of the bluetooth adapter | | ||
| bondedDevices | Returns the list of bonded (paired) devices | | ||
| startScan | Starts a scan for Bluetooth devices | | ||
| stopScan | Stop an existing scan for Bluetooth devices | | ||
| isScanningNow | Checks whether the Bluetooth adapter is currently scanning. | | ||
| isScanning | Stream whether the device is scanning for BL devices. | | ||
| scanResults | Stream of found devices during scan | | ||
| turnOn | Requests to turns the bluetooth adapter on | | ||
| bondDevice | Requests to create a bond with a bluetooth device | | ||
| connect | Tries to connect with a bluetooth device | | ||
|
||
### BluetoothConnection | ||
| | Description | | ||
|:------------|:---------------------------------------------------------------------------------------------------| | ||
| input | The stream of data received from the connected BL device | | ||
| output | A stream sink to send byte data to the connected BL device | | ||
| writeString | A helper to send utf-8 encoded strings to the remote device | | ||
| isConnected | Indicates whether the connection is still open. | | ||
| dispose | This should be called, when the Connection is no longer needed and will call `finish` (see below). | | ||
| finish | This will wait for any ongoing writes to be finished and gracefully close the connection. | | ||
| close | This will immediately close the connection. | | ||
|
||
## Acknowledgement | ||
flutter_blue_classic is loosely based on flutter_bluetooth_serial. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
include: package:flutter_lints/flutter.yaml | ||
|
||
# Additional information about this file can be found at | ||
# https://dart.dev/guides/language/analysis-options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea/workspace.xml | ||
/.idea/libraries | ||
.DS_Store | ||
/build | ||
/captures | ||
.cxx | ||
gradle/* | ||
gradlew | ||
gradlew.bat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
group 'dev.lenhart.flutter_blue_classic' | ||
version '1.0-SNAPSHOT' | ||
|
||
buildscript { | ||
ext.kotlin_version = '1.7.10' | ||
repositories { | ||
google() | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
classpath 'com.android.tools.build:gradle:7.3.1' | ||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||
} | ||
} | ||
|
||
allprojects { | ||
repositories { | ||
google() | ||
mavenCentral() | ||
} | ||
} | ||
|
||
apply plugin: 'com.android.library' | ||
apply plugin: 'kotlin-android' | ||
|
||
android { | ||
if (project.android.hasProperty("namespace")) { | ||
namespace 'dev.lenhart.flutter_blue_classic' | ||
} | ||
|
||
compileSdk 34 | ||
|
||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
|
||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
|
||
sourceSets { | ||
main.java.srcDirs += 'src/main/kotlin' | ||
test.java.srcDirs += 'src/test/kotlin' | ||
} | ||
|
||
defaultConfig { | ||
minSdkVersion 21 | ||
} | ||
|
||
dependencies { | ||
testImplementation 'org.jetbrains.kotlin:kotlin-test' | ||
testImplementation 'org.mockito:mockito-core:5.0.0' | ||
} | ||
|
||
testOptions { | ||
unitTests.all { | ||
useJUnitPlatform() | ||
|
||
testLogging { | ||
events "passed", "skipped", "failed", "standardOut", "standardError" | ||
outputs.upToDateWhen {false} | ||
showStandardStreams = true | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rootProject.name = 'flutter_blue_classic' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="dev.lenhart.flutter_blue_classic"> | ||
</manifest> |
40 changes: 40 additions & 0 deletions
40
android/src/main/kotlin/dev/lenhart/flutter_blue_classic/AdapterStateReceiver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package dev.lenhart.flutter_blue_classic | ||
|
||
import android.bluetooth.BluetoothAdapter | ||
import android.content.BroadcastReceiver | ||
import android.content.Context | ||
import android.content.Intent | ||
import io.flutter.plugin.common.EventChannel | ||
|
||
class AdapterStateReceiver : EventChannel.StreamHandler{ | ||
companion object{ | ||
const val CHANNEL_NAME: String = "${BlueClassicHelper.NAMESPACE}/adapterState" | ||
} | ||
|
||
private var adapterStateEventSink: EventChannel.EventSink? = null | ||
|
||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) { | ||
adapterStateEventSink = events | ||
} | ||
|
||
override fun onCancel(arguments: Any?) { | ||
adapterStateEventSink = null | ||
} | ||
|
||
val mBluetoothAdapterStateReceiver: BroadcastReceiver = object : BroadcastReceiver() { | ||
override fun onReceive(context: Context, intent: Intent) { | ||
val action = intent.action | ||
if (action == null || BluetoothAdapter.ACTION_STATE_CHANGED != action) { | ||
return | ||
} | ||
val adapterState = | ||
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) | ||
|
||
adapterStateEventSink.let { it?.success( | ||
BlueClassicHelper.adapterStateString( | ||
adapterState | ||
) | ||
) } | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
android/src/main/kotlin/dev/lenhart/flutter_blue_classic/BlueClassicHelper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package dev.lenhart.flutter_blue_classic | ||
|
||
import android.bluetooth.BluetoothAdapter | ||
import android.bluetooth.BluetoothDevice | ||
|
||
class BlueClassicHelper { | ||
companion object { | ||
const val NAMESPACE: String = "blue_classic" | ||
const val METHOD_CHANNEL_NAME: String = "$NAMESPACE/methods" | ||
const val ERROR_ADDRESS_INVALID : String= "addressInvalid" | ||
|
||
fun adapterStateString(state: Int): String { | ||
return when (state) { | ||
BluetoothAdapter.STATE_OFF -> "off" | ||
BluetoothAdapter.STATE_ON -> "on" | ||
BluetoothAdapter.STATE_TURNING_OFF -> "turningOff" | ||
BluetoothAdapter.STATE_TURNING_ON -> "turningOn" | ||
else -> "unknown" | ||
} | ||
} | ||
|
||
|
||
fun bondStateString(state: Int): String { | ||
return when (state) { | ||
BluetoothDevice.BOND_BONDING -> "bonding" | ||
BluetoothDevice.BOND_BONDED -> "bonded" | ||
BluetoothDevice.BOND_NONE -> "none" | ||
else -> "unknown" | ||
} | ||
} | ||
|
||
fun bluetoothDeviceToMap(device: BluetoothDevice): MutableMap<String, Any> { | ||
val entry: MutableMap<String, Any> = HashMap() | ||
entry["address"] = device.address | ||
entry["name"] = device.name ?: "" | ||
entry["bondState"] = bondStateString(device.bondState) | ||
return entry | ||
} | ||
} | ||
} |
Oops, something went wrong.