forked from edufolly/flutter_bluetooth_serial
-
Notifications
You must be signed in to change notification settings - Fork 8
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
Showing
42 changed files
with
1,776 additions
and
297 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
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 |
---|---|---|
@@ -1,9 +1,9 @@ | ||
|
||
# `flutter_bluetooth_serial` | ||
# `flutter_bluetooth_serial_ble` | ||
|
||
[![pub package](https://img.shields.io/pub/v/flutter_bluetooth_serial.svg)](https://pub.dartlang.org/packages/flutter_bluetooth_serial) | ||
[![pub package](https://img.shields.io/pub/v/flutter_bluetooth_serial_ble.svg)](https://pub.dartlang.org/packages/flutter_bluetooth_serial_ble) | ||
|
||
Flutter basic implementation for Classical Bluetooth (only RFCOMM for now). | ||
Flutter basic implementation for Classical Bluetooth (only RFCOMM for now), and now also BLE. I hacked out parts of [SimpleBluetoothLeTerminal](https://github.com/kai-morich/SimpleBluetoothLeTerminal) and glued them to [flutter_bluetooth_serial](https://github.com/edufolly/flutter_bluetooth_serial) and now `BluetoothConnection.toAddress` accepts a second parameter, `type`, defaulting to `AUTO`, giving the behavior of trying to connect with the usual BT Classic mechanism first, then switching to BLE if that fails. (Note this makes the default behavior slow to connect to a BLE device.) It should work out of the box, a drop-in replacement of the previous version, aside from the addition of two "_ble"s to the imports. Hasn't been tested very rigorously yet, sorry. I do note that BLE connection fails the first time I try after installing the app, and is fine after that - probably some permissions thing in the wrong place. Check permissions if you have trouble. | ||
|
||
|
||
## Features | ||
|
@@ -36,7 +36,7 @@ For now there is only Android support. | |
# Add dependency to `pubspec.yaml` of your project. | ||
dependencies: | ||
# ... | ||
flutter_bluetooth_serial: ^0.3.2 | ||
flutter_bluetooth_serial_ble: ^0.5.0 | ||
``` | ||
#### Installing | ||
|
@@ -50,7 +50,7 @@ flutter pub get | |
|
||
#### Importing | ||
```dart | ||
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart'; | ||
import 'package:flutter_bluetooth_serial_ble/flutter_bluetooth_serial_ble.dart'; | ||
``` | ||
|
||
#### Usage | ||
|
@@ -106,6 +106,7 @@ You might also want to check [milestones](https://github.com/edufolly/flutter_bl | |
- [Eduardo Folly](mailto:[email protected]) | ||
- [Martin Mauch](mailto:[email protected]) | ||
- [Patryk Ludwikowski](mailto:[email protected]) | ||
- https://github.com/kai-morich/SimpleBluetoothLeTerminal for BLE code | ||
|
||
After version 0.3.0 we have a lot of collaborators. If you would like to be credited, please send me an [email](mailto:[email protected]). | ||
|
||
|
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
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
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 |
---|---|---|
@@ -1 +1 @@ | ||
rootProject.name = 'flutter_bluetooth_serial' | ||
rootProject.name = 'flutter_bluetooth_serial_ble' |
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
184 changes: 9 additions & 175 deletions
184
android/src/main/java/io/github/edufolly/flutterbluetoothserial/BluetoothConnection.java
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 |
---|---|---|
@@ -1,186 +1,20 @@ | ||
package io.github.edufolly.flutterbluetoothserial; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.util.UUID; | ||
import java.util.Arrays; | ||
|
||
import android.bluetooth.BluetoothAdapter; | ||
import android.bluetooth.BluetoothDevice; | ||
import android.bluetooth.BluetoothSocket; | ||
|
||
/// Universal Bluetooth serial connection class (for Java) | ||
public abstract class BluetoothConnection | ||
{ | ||
protected static final UUID DEFAULT_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); | ||
|
||
protected BluetoothAdapter bluetoothAdapter; | ||
|
||
protected ConnectionThread connectionThread = null; | ||
|
||
public boolean isConnected() { | ||
return connectionThread != null && connectionThread.requestedClosing != true; | ||
} | ||
|
||
|
||
|
||
public BluetoothConnection(BluetoothAdapter bluetoothAdapter) { | ||
this.bluetoothAdapter = bluetoothAdapter; | ||
} | ||
|
||
|
||
|
||
// @TODO . `connect` could be done perfored on the other thread | ||
// @TODO . `connect` parameter: timeout | ||
// @TODO . `connect` other methods than `createRfcommSocketToServiceRecord`, including hidden one raw `createRfcommSocket` (on channel). | ||
// @TODO ? how about turning it into factoried? | ||
public interface BluetoothConnection { | ||
public boolean isConnected(); | ||
/// Connects to given device by hardware address | ||
public void connect(String address, UUID uuid) throws IOException { | ||
if (isConnected()) { | ||
throw new IOException("already connected"); | ||
} | ||
|
||
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address); | ||
if (device == null) { | ||
throw new IOException("device not found"); | ||
} | ||
|
||
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid); // @TODO . introduce ConnectionMethod | ||
if (socket == null) { | ||
throw new IOException("socket connection not established"); | ||
} | ||
|
||
// Cancel discovery, even though we didn't start it | ||
bluetoothAdapter.cancelDiscovery(); | ||
|
||
socket.connect(); | ||
|
||
connectionThread = new ConnectionThread(socket); | ||
connectionThread.start(); | ||
} | ||
public void connect(String address, UUID uuid) throws IOException; | ||
/// Connects to given device by hardware address (default UUID used) | ||
public void connect(String address) throws IOException { | ||
connect(address, DEFAULT_UUID); | ||
} | ||
|
||
public void connect(String address) throws IOException; | ||
/// Disconnects current session (ignore if not connected) | ||
public void disconnect() { | ||
if (isConnected()) { | ||
connectionThread.cancel(); | ||
connectionThread = null; | ||
} | ||
} | ||
|
||
/// Writes to connected remote device | ||
public void write(byte[] data) throws IOException { | ||
if (!isConnected()) { | ||
throw new IOException("not connected"); | ||
} | ||
|
||
connectionThread.write(data); | ||
} | ||
|
||
public void disconnect(); | ||
/// Writes to connected remote device | ||
public void write(byte[] data) throws IOException; | ||
/// Callback for reading data. | ||
protected abstract void onRead(byte[] data); | ||
|
||
public void onRead(byte[] data); | ||
/// Callback for disconnection. | ||
protected abstract void onDisconnected(boolean byRemote); | ||
|
||
/// Thread to handle connection I/O | ||
private class ConnectionThread extends Thread { | ||
private final BluetoothSocket socket; | ||
private final InputStream input; | ||
private final OutputStream output; | ||
private boolean requestedClosing = false; | ||
|
||
ConnectionThread(BluetoothSocket socket) { | ||
this.socket = socket; | ||
InputStream tmpIn = null; | ||
OutputStream tmpOut = null; | ||
|
||
try { | ||
tmpIn = socket.getInputStream(); | ||
tmpOut = socket.getOutputStream(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
this.input = tmpIn; | ||
this.output = tmpOut; | ||
} | ||
|
||
/// Thread main code | ||
public void run() { | ||
byte[] buffer = new byte[1024]; | ||
int bytes; | ||
|
||
while (!requestedClosing) { | ||
try { | ||
bytes = input.read(buffer); | ||
|
||
onRead(Arrays.copyOf(buffer, bytes)); | ||
} catch (IOException e) { | ||
// `input.read` throws when closed by remote device | ||
break; | ||
} | ||
} | ||
|
||
// Make sure output stream is closed | ||
if (output != null) { | ||
try { | ||
output.close(); | ||
} | ||
catch (Exception e) {} | ||
} | ||
|
||
// Make sure input stream is closed | ||
if (input != null) { | ||
try { | ||
input.close(); | ||
} | ||
catch (Exception e) {} | ||
} | ||
|
||
// Callback on disconnected, with information which side is closing | ||
onDisconnected(!requestedClosing); | ||
|
||
// Just prevent unnecessary `cancel`ing | ||
requestedClosing = true; | ||
} | ||
|
||
/// Writes to output stream | ||
public void write(byte[] bytes) { | ||
try { | ||
output.write(bytes); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
/// Stops the thread, disconnects | ||
public void cancel() { | ||
if (requestedClosing) { | ||
return; | ||
} | ||
requestedClosing = true; | ||
|
||
// Flush output buffers befoce closing | ||
try { | ||
output.flush(); | ||
} | ||
catch (Exception e) {} | ||
|
||
// Close the connection socket | ||
if (socket != null) { | ||
try { | ||
// Might be useful (see https://stackoverflow.com/a/22769260/4880243) | ||
Thread.sleep(111); | ||
|
||
socket.close(); | ||
} | ||
catch (Exception e) {} | ||
} | ||
} | ||
} | ||
public void onDisconnected(boolean byRemote); | ||
} |
26 changes: 26 additions & 0 deletions
26
android/src/main/java/io/github/edufolly/flutterbluetoothserial/BluetoothConnectionBase.java
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,26 @@ | ||
package io.github.edufolly.flutterbluetoothserial; | ||
|
||
public abstract class BluetoothConnectionBase implements io.github.edufolly.flutterbluetoothserial.BluetoothConnection { | ||
public interface OnReadCallback { | ||
public void onRead(byte[] data); | ||
} | ||
public interface OnDisconnectedCallback { | ||
public void onDisconnected(boolean byRemote); | ||
} | ||
|
||
final OnReadCallback onReadCallback; | ||
final OnDisconnectedCallback onDisconnectedCallback; | ||
|
||
public BluetoothConnectionBase(OnReadCallback onReadCallback, OnDisconnectedCallback onDisconnectedCallback) { | ||
this.onReadCallback = onReadCallback; | ||
this.onDisconnectedCallback = onDisconnectedCallback; | ||
} | ||
|
||
public void onRead(byte[] data) { | ||
onReadCallback.onRead(data); | ||
} | ||
|
||
public void onDisconnected(boolean byRemote) { | ||
onDisconnectedCallback.onDisconnected(byRemote); | ||
} | ||
} |
Oops, something went wrong.