Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #1

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6d2bc13
fix(rfcomm) solved issue with connecting
rGradov Jul 20, 2023
03de0da
connection0[0] = new BluetoothConnectionClassic(orc, odc,…
rGradov Jul 20, 2023
06ab6cf
copnnected
rGradov Jul 20, 2023
fb1d959
add ; System.out.println(" == not connected ===")
rGradov Jul 20, 2023
8ccb5e8
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uu…
rGradov Jul 20, 2023
78bb428
solved issue with socket
rGradov Jul 20, 2023
ef2d5fd
solved issue with socket
rGradov Jul 20, 2023
9f1ae7a
solved issue
rGradov Jul 20, 2023
86bd7d1
add error handling ^
rGradov Jul 20, 2023
0c9c705
addd property
rGradov Jul 20, 2023
4447934
System.out.print("buffer read start");
rGradov Jul 20, 2023
5499e0f
Log.d(TAG, "Input stream was disconnected", e);
rGradov Jul 20, 2023
4a47a23
solved eerors
rGradov Jul 20, 2023
525edd7
solved issue
rGradov Jul 20, 2023
f15acef
FIX
rGradov Jul 20, 2023
b5f40a6
System.out.println(e.getMessage());
rGradov Jul 20, 2023
e7b0058
System.out.println("connection socket status"+ socket.isConnected()…
rGradov Jul 20, 2023
f642e06
id 3
rGradov Jul 20, 2023
b823929
bla blasdasd
rGradov Jul 20, 2023
8f0c96b
solved
rGradov Jul 20, 2023
7d18053
@Override
rGradov Jul 20, 2023
dedbc2d
solved issue with
rGradov Jul 20, 2023
62edab9
remove run from constructor
rGradov Jul 20, 2023
4791f70
remove run from constructor
rGradov Jul 20, 2023
c72417d
solved issue add finaly
rGradov Jul 20, 2023
a514b60
bla bla
rGradov Jul 20, 2023
5b11588
runtime get message
rGradov Jul 20, 2023
13871a3
add byffer while
rGradov Jul 20, 2023
76daadf
try to ensure permission
rGradov Jul 25, 2023
b7749ca
- remove
rGradov Jul 25, 2023
8c116f8
- return code from dock
rGradov Jul 25, 2023
23a0cfe
- add logs + add result.error
rGradov Jul 27, 2023
fa8b81e
- solved crash app error
rGradov Jul 27, 2023
be162dd
- refactor java code, create two new methods run and close
rGradov Jul 27, 2023
1037bc2
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
rGradov Aug 3, 2023
ee57af9
<uses-permission android:name="android.permission.ACCESS_FINE_LOCA…
rGradov Aug 3, 2023
047d3d3
remove unneded permission
rGradov Aug 3, 2023
0d5265d
remove unneded permission
rGradov Aug 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.edufolly.flutterbluetoothserial">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
package="io.github.edufolly.flutterbluetoothserial" xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

<!-- From SimpleBluetoothLeTerminal -->
<!-- <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />-->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package io.github.edufolly.flutterbluetoothserial;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;

public interface BluetoothConnection {
public boolean isConnected();
/// Connects to given device by hardware address
public void connect(String address, UUID uuid) throws IOException;
public void connect(String address, UUID uuid) throws Exception;
/// Connects to given device by hardware address (default UUID used)
public void connect(String address) throws IOException;
public void connect(String address) throws Exception;
/// Disconnects current session (ignore if not connected)
public void disconnect();
/// Writes to connected remote device
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package io.github.edufolly.flutterbluetoothserial;

import static android.content.ContentValues.TAG;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.Arrays;
import java.util.function.Consumer;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

/// Universal Bluetooth serial connection class (for Java)
public class BluetoothConnectionClassic extends BluetoothConnectionBase
Expand All @@ -21,7 +26,7 @@ public class BluetoothConnectionClassic extends BluetoothConnectionBase
protected ConnectionThread connectionThread = null;

public boolean isConnected() {
return connectionThread != null && connectionThread.requestedClosing != true;
return connectionThread != null && !connectionThread.requestedClosing;
}


Expand All @@ -37,33 +42,53 @@ public BluetoothConnectionClassic(OnReadCallback onReadCallback, OnDisconnectedC
// @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 void connect(String address, UUID uuid) throws IOException {
public void connect(String address, UUID uuid) throws Exception {
System.out.println("start connecting to bluetooth");
if (isConnected()) {
throw new IOException("already connected");
}

BluetoothSocket socket = null;
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if (device == null) {
throw new IOException("device not found");
}
socket = device.createRfcommSocketToServiceRecord(DEFAULT_UUID);

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();
if(socket == null) {
throw new IOException("socket are null");
}
run(socket);

connectionThread = new ConnectionThread(socket);
connectionThread.start();
}

public void connect(String address) throws IOException {
public void connect(String address) throws Exception {
connect(address, DEFAULT_UUID);
}
private void run(BluetoothSocket mmSocket) throws IOException {
Log.e(TAG, "star socket connection", null);
if(bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
} catch (IOException connectException) {
Log.e(TAG, "Could not connect", connectException);
cancelSocket(mmSocket);
return;
}
connectionThread = new ConnectionThread(mmSocket);
connectionThread.start();
}
private void cancelSocket(BluetoothSocket mmSocket) {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the client socket", e);
}
}

public void disconnect() {
if (isConnected()) {
Expand All @@ -85,37 +110,52 @@ private class ConnectionThread extends Thread {
private final BluetoothSocket socket;
private final InputStream input;
private final OutputStream output;
private byte[] mmBuffer;
private boolean requestedClosing = false;

ConnectionThread(BluetoothSocket socket) {
ConnectionThread(BluetoothSocket socket) throws IOException {
this.socket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;

try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();

} catch (IOException e) {
e.printStackTrace();
System.out.println("connection input "+e.getMessage());
}
try {
tmpOut = socket.getOutputStream();
}catch (IOException e){

System.out.println("connection output "+e.getMessage());

} if(tmpIn !=null){
System.out.println("tmp"+tmpIn.available());
}
this.input = tmpIn;
this.output = tmpOut;
}

/// Thread main code

public void run() {
byte[] buffer = new byte[1024];
Log.i(TAG, "BEGIN BT Monitor");
mmBuffer = new byte[1024];
int bytes;

while (!requestedClosing) {
System.out.println("input available try to start while");
while (true) {
System.out.print("buffer while");
try {
bytes = input.read(buffer);

onRead(Arrays.copyOf(buffer, bytes));
bytes = input.read(mmBuffer);
System.out.print("bytes:"+bytes);
onRead(Arrays.copyOf(mmBuffer, bytes));
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
// `input.read` throws when closed by remote device
break;
} finally {
System.out.print("buffer"+ Arrays.toString(mmBuffer));
}
}

Expand All @@ -124,15 +164,17 @@ public void run() {
try {
output.close();
}
catch (Exception e) {}
catch (Exception e) {
System.out.println(e.getMessage());
}
}

// Make sure input stream is closed
if (input != null) {
try {
input.close();
}
catch (Exception e) {}
try {
input.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
}

// Callback on disconnected, with information which side is closing
Expand All @@ -147,7 +189,7 @@ public void write(byte[] bytes) {
try {
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}

Expand All @@ -162,7 +204,10 @@ public void cancel() {
try {
output.flush();
}
catch (Exception e) {}
catch (Exception e) {
System.out.println(e.getMessage());

}

// Close the connection socket
if (socket != null) {
Expand All @@ -172,7 +217,10 @@ public void cancel() {

socket.close();
}
catch (Exception e) {}
catch (Exception e) {
System.out.println(e.getMessage());

}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ public void error(String code, String message, Object details) {

case 4: //case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY: // @TODO , Symbol not found?
// This pairing method requires to enter the generated and displayed pairing key
// on the remote device. It looks like basic asymmetric cryptography was used.
case 5: //case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN: // @TODO , Symbol not found?
// Same as previous, but for 4 digit pin.
{
Expand Down Expand Up @@ -545,6 +544,7 @@ public void onMethodCall(MethodCall call, Result result) {
ensurePermissions(result::success);
break;


case "getState":
result.success(bluetoothAdapter.getState());
break;
Expand Down Expand Up @@ -930,7 +930,6 @@ public void onReceive(Context context, Intent intent) {
}

boolean isLE = call.hasArgument("isLE") && Boolean.TRUE.equals(call.<Boolean>argument("isLE"));

String address;
try {
address = call.argument("address");
Expand All @@ -948,7 +947,6 @@ public void onReceive(Context context, Intent intent) {
int id = ++lastConnectionId;

EventSink[] readSink = {null};

// I think this code is to effect disconnection when the plugin is unloaded or something?
EventChannel readChannel = new EventChannel(messenger, PLUGIN_NAMESPACE + "/read/" + id);
// If canceled by local, disconnects - in other case, by remote, does nothing
Expand Down Expand Up @@ -989,6 +987,7 @@ public void onRead(byte[] data) {
BluetoothConnectionBase.OnDisconnectedCallback odc = new BluetoothConnectionBase.OnDisconnectedCallback() {
@Override
public void onDisconnected(boolean byRemote) {
System.out.println("");
activity.runOnUiThread(() -> {
if (byRemote) {
Log.d(TAG, "onDisconnected by remote (id: " + id + ")");
Expand All @@ -1002,22 +1001,17 @@ public void onDisconnected(boolean byRemote) {
});
}
};

if (isLE) {
connection0[0] = new BluetoothConnectionLE(orc, odc, activeContext);
} else {
connection0[0] = new BluetoothConnectionClassic(orc, odc, bluetoothAdapter);
}
connection0[0] = new BluetoothConnectionClassic(orc, odc, bluetoothAdapter);
connection = connection0[0];
connections.put(id, connection);

Log.d(TAG, "Connecting to " + address + " (id: " + id + ")");

Log.d(TAG, "Connecting to " + address + " (id: " + id + ")");
AsyncTask.execute(() -> {
try {
connection.connect(address);
activity.runOnUiThread(() -> result.success(id));
} catch (Exception ex) {
Log.d(TAG, "error connect to address:" + address);
activity.runOnUiThread(() -> result.error("connect_error", ex.getMessage(), exceptionToString(ex)));
connections.remove(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void connect(String address) throws IOException {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
//System.out.println("connecting...");
System.out.println("connecting...");
connected = Connected.Pending;
SerialSocket socket = new SerialSocket(ctx, device);

Expand Down
22 changes: 15 additions & 7 deletions lib/BluetoothConnection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ part of flutter_bluetooth_serial_ble;
enum ConnectionType {
CLASSIC,
BLE,

/// Try BT classic, then on failure try BLE
AUTO,

/// Try BLE, then on failure try BT classic
AUTO_BUT_TRY_BLE_FIRST
}
Expand All @@ -27,7 +29,6 @@ class BluetoothConnection {

/// This ID identifies real full `BluetoothConenction` object on platform side code.
final int? _id;

final EventChannel _readChannel;
late StreamSubscription<Uint8List> _readStreamSubscription;
late StreamController<Uint8List> _readStreamController;
Expand Down Expand Up @@ -65,35 +66,42 @@ class BluetoothConnection {
}

/// Returns connection to given address.
static Future<BluetoothConnection> toAddress(String? address, {ConnectionType type = ConnectionType.AUTO}) async { //DUMMY //THINK Expose bc/ble?
static Future<BluetoothConnection> toAddress(String? address,
{ConnectionType type = ConnectionType.AUTO}) async {
//DUMMY //THINK Expose bc/ble?
switch (type) {
case ConnectionType.AUTO:
try {
return await toAddressBC(address);
} catch (e, s) {
// Bluetooth classic failed; try BLE
return toAddressBLE(address);
return toAddressBC(address);
}
case ConnectionType.AUTO_BUT_TRY_BLE_FIRST:
try {
return await toAddressBLE(address);
return await toAddressBC(address);
} catch (e, s) {
// BLE failed; try bluetooth classic
return toAddressBC(address);
}
case ConnectionType.CLASSIC:
return toAddressBC(address);
case ConnectionType.BLE:
return toAddressBLE(address);
return toAddressBC(address);
}
}

static Future<BluetoothConnection> disconnect() async {

// Sorry for pseudo-factory, but `factory` keyword disallows `Future`.
return BluetoothConnection._consumeConnectionID(
await FlutterBluetoothSerial._methodChannel.invokeMethod('disconnect'));
}

static Future<BluetoothConnection> toAddressBLE(String? address) async {
// Sorry for pseudo-factory, but `factory` keyword disallows `Future`.
return BluetoothConnection._consumeConnectionID(await FlutterBluetoothSerial
._methodChannel
.invokeMethod('connect', {"address": address, "isLE": true}));

}

static Future<BluetoothConnection> toAddressBC(String? address) async {
Expand Down
Loading