mirror of
https://github.com/Team-xManager/xManager.git
synced 2025-01-13 20:11:35 +01:00
354 lines
8.1 KiB
Java
354 lines
8.1 KiB
Java
package com.xc3fff0e.xmanager;
|
|
|
|
import android.bluetooth.BluetoothAdapter;
|
|
import android.bluetooth.BluetoothDevice;
|
|
import android.bluetooth.BluetoothServerSocket;
|
|
import android.bluetooth.BluetoothSocket;
|
|
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.HashMap;
|
|
import java.util.UUID;
|
|
|
|
public class BluetoothController {
|
|
public static final String STATE_NONE = "none";
|
|
public static final String STATE_LISTEN = "listen";
|
|
public static final String STATE_CONNECTING = "connecting";
|
|
public static final String STATE_CONNECTED = "connected";
|
|
|
|
private AcceptThread acceptThread;
|
|
private ConnectThread connectThread;
|
|
private ConnectedThread connectedThread;
|
|
|
|
private String state = STATE_NONE;
|
|
|
|
private static BluetoothController instance;
|
|
|
|
public static synchronized BluetoothController getInstance() {
|
|
if(instance == null) {
|
|
instance = new BluetoothController();
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
public synchronized void start(BluetoothConnect bluetoothConnect, BluetoothConnect.BluetoothConnectionListener listener, String tag, UUID uuid, BluetoothAdapter bluetoothAdapter) {
|
|
if (connectThread != null) {
|
|
connectThread.cancel();
|
|
connectThread = null;
|
|
}
|
|
|
|
if (connectedThread != null) {
|
|
connectedThread.cancel();
|
|
connectedThread = null;
|
|
}
|
|
|
|
if (acceptThread != null) {
|
|
acceptThread.cancel();
|
|
acceptThread = null;
|
|
}
|
|
|
|
acceptThread = new AcceptThread(bluetoothConnect, listener, tag, uuid, bluetoothAdapter);
|
|
acceptThread.start();}
|
|
|
|
public synchronized void connect(BluetoothDevice device, BluetoothConnect bluetoothConnect, BluetoothConnect.BluetoothConnectionListener listener, String tag, UUID uuid, BluetoothAdapter bluetoothAdapter) {
|
|
if (state.equals(STATE_CONNECTING)) {
|
|
if (connectThread != null) {
|
|
connectThread.cancel();
|
|
connectThread = null;
|
|
}
|
|
}
|
|
|
|
if (connectedThread != null) {
|
|
connectedThread.cancel();
|
|
connectedThread = null;
|
|
}
|
|
|
|
connectThread = new ConnectThread(device, bluetoothConnect, listener, tag, uuid, bluetoothAdapter);
|
|
connectThread.start();
|
|
}
|
|
|
|
public synchronized void connected(BluetoothSocket socket, final BluetoothDevice device, BluetoothConnect bluetoothConnect, final BluetoothConnect.BluetoothConnectionListener listener, final String tag) {
|
|
if (connectThread != null) {
|
|
connectThread.cancel();
|
|
connectThread = null;
|
|
}
|
|
|
|
if (connectedThread != null) {
|
|
connectedThread.cancel();
|
|
connectedThread = null;
|
|
}
|
|
|
|
if (acceptThread != null) {
|
|
acceptThread.cancel();
|
|
acceptThread = null;
|
|
}
|
|
|
|
connectedThread = new ConnectedThread(socket, bluetoothConnect, listener, tag);
|
|
connectedThread.start();
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
HashMap<String, Object> deviceMap = new HashMap<>();
|
|
deviceMap.put("name", device.getName());
|
|
deviceMap.put("address", device.getAddress());
|
|
|
|
listener.onConnected(tag, deviceMap);
|
|
}
|
|
});
|
|
}
|
|
|
|
public synchronized void stop(BluetoothConnect bluetoothConnect, final BluetoothConnect.BluetoothConnectionListener listener, final String tag) {
|
|
if (connectThread != null) {
|
|
connectThread.cancel();
|
|
connectThread = null;
|
|
}
|
|
|
|
if (connectedThread != null) {
|
|
connectedThread.cancel();
|
|
connectedThread = null;
|
|
}
|
|
|
|
if (acceptThread != null) {
|
|
acceptThread.cancel();
|
|
acceptThread = null;
|
|
}
|
|
|
|
state = STATE_NONE;
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
listener.onConnectionStopped(tag);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void write(byte[] out) {
|
|
ConnectedThread r;
|
|
|
|
synchronized (this) {
|
|
if (!state.equals(STATE_CONNECTED)) return;
|
|
r = connectedThread;
|
|
}
|
|
|
|
r.write(out);
|
|
}
|
|
|
|
public void connectionFailed(BluetoothConnect bluetoothConnect, final BluetoothConnect.BluetoothConnectionListener listener, final String tag, final String message) {
|
|
state = STATE_NONE;
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
listener.onConnectionError(tag, state, message);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void connectionLost(BluetoothConnect bluetoothConnect, final BluetoothConnect.BluetoothConnectionListener listener, final String tag) {
|
|
state = STATE_NONE;
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
listener.onConnectionError(tag, state, "Bluetooth connection is disconnected");
|
|
}
|
|
});
|
|
}
|
|
|
|
public String getState() {
|
|
return state;
|
|
}
|
|
|
|
private class AcceptThread extends Thread {
|
|
private BluetoothServerSocket serverSocket;
|
|
|
|
private BluetoothConnect bluetoothConnect;
|
|
private BluetoothConnect.BluetoothConnectionListener listener;
|
|
private String tag;
|
|
|
|
public AcceptThread(BluetoothConnect bluetoothConnect, BluetoothConnect.BluetoothConnectionListener listener, String tag, UUID uuid, BluetoothAdapter bluetoothAdapter) {
|
|
this.bluetoothConnect = bluetoothConnect;
|
|
this.listener = listener;
|
|
this.tag = tag;
|
|
|
|
try {
|
|
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(tag, uuid);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
state = STATE_LISTEN;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
BluetoothSocket bluetoothSocket;
|
|
|
|
while (!state.equals(STATE_CONNECTED)) {
|
|
try {
|
|
bluetoothSocket = serverSocket.accept();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
break;
|
|
}
|
|
|
|
if (bluetoothSocket != null) {
|
|
synchronized (BluetoothController.this) {
|
|
switch (state) {
|
|
case STATE_LISTEN:
|
|
case STATE_CONNECTING:
|
|
connected(bluetoothSocket, bluetoothSocket.getRemoteDevice(), bluetoothConnect, listener, tag);
|
|
break;
|
|
case STATE_NONE:
|
|
case STATE_CONNECTED:
|
|
try {
|
|
bluetoothSocket.close();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void cancel() {
|
|
try {
|
|
serverSocket.close();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
private class ConnectThread extends Thread {
|
|
private BluetoothDevice device;
|
|
private BluetoothSocket socket;
|
|
|
|
private BluetoothConnect bluetoothConnect;
|
|
private BluetoothConnect.BluetoothConnectionListener listener;
|
|
private String tag;
|
|
private BluetoothAdapter bluetoothAdapter;
|
|
|
|
public ConnectThread(BluetoothDevice device, BluetoothConnect bluetoothConnect, BluetoothConnect.BluetoothConnectionListener listener, String tag, UUID uuid, BluetoothAdapter bluetoothAdapter) {
|
|
this.device = device;
|
|
this.bluetoothConnect = bluetoothConnect;
|
|
this.listener = listener;
|
|
this.tag = tag;
|
|
this.bluetoothAdapter = bluetoothAdapter;
|
|
|
|
try {
|
|
socket = device.createRfcommSocketToServiceRecord(uuid);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
state = STATE_CONNECTING;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
bluetoothAdapter.cancelDiscovery();
|
|
|
|
try {
|
|
socket.connect();
|
|
} catch (Exception e) {
|
|
try {
|
|
socket.close();
|
|
} catch (Exception e2) {
|
|
e2.printStackTrace();
|
|
}
|
|
connectionFailed(bluetoothConnect, listener, tag, e.getMessage());
|
|
return;
|
|
}
|
|
|
|
synchronized (BluetoothController.this) {
|
|
connectThread = null;
|
|
}
|
|
|
|
connected(socket, device, bluetoothConnect, listener, tag);
|
|
}
|
|
|
|
public void cancel() {
|
|
try {
|
|
socket.close();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
private class ConnectedThread extends Thread {
|
|
private BluetoothSocket socket;
|
|
private InputStream inputStream;
|
|
private OutputStream outputStream;
|
|
|
|
private BluetoothConnect bluetoothConnect;
|
|
private BluetoothConnect.BluetoothConnectionListener listener;
|
|
private String tag;
|
|
|
|
public ConnectedThread(BluetoothSocket socket, BluetoothConnect bluetoothConnect, BluetoothConnect.BluetoothConnectionListener listener, String tag) {
|
|
this.bluetoothConnect = bluetoothConnect;
|
|
this.listener = listener;
|
|
this.tag = tag;
|
|
|
|
this.socket = socket;
|
|
|
|
try {
|
|
inputStream = socket.getInputStream();
|
|
outputStream = socket.getOutputStream();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
state = STATE_CONNECTED;
|
|
}
|
|
|
|
public void run() {
|
|
while (state.equals(STATE_CONNECTED)) {
|
|
try {
|
|
final byte[] buffer = new byte[1024];
|
|
final int bytes = inputStream.read(buffer);
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
listener.onDataReceived(tag, buffer, bytes);
|
|
}
|
|
});
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
connectionLost(bluetoothConnect, listener, tag);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void write(final byte[] buffer) {
|
|
try {
|
|
outputStream.write(buffer);
|
|
|
|
bluetoothConnect.getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
listener.onDataSent(tag, buffer);
|
|
}
|
|
});
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public void cancel() {
|
|
try {
|
|
socket.close();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
} |