public class BluetoothConnectionService extends Service {
private WeightScaleManager weightScaleManager;
private BluetoothDevice connectedDevice;
private BluetoothSocket socket;
private boolean isConnected = false;
private static final int BLUETOOTH_PERMISSION_REQUEST_CODE = 1;
private static final UUID SPP_UUID = [Link]("00001101-0000-1000-
8000-00805F9B34FB");
private ReadsViewModel viewModel;
private static BluetoothConnectionService instance;
public static final String ACTION_CONNECT =
"[Link].ACTION_CONNECT";
public BluetoothConnectionService() {
// Constructor - no initialization needed here
}
public static BluetoothConnectionService getInstance() {
return instance;
}
@Override
public void onCreate() {
[Link]();
instance = this; // Set the singleton instance
weightScaleManager = new WeightScaleManager(this); // Correctly
passing the service context
viewModel = [Link](this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && ACTION_CONNECT.equals([Link]())) {
String deviceAddress = [Link]("DEVICE_ADDRESS");
if (deviceAddress != null) {
connectToDevice(deviceAddress);
} else {
Log.i("BluetoothConnectionService", "No device address
provided.");
}
}
return START_STICKY;
}
public boolean isConnected() {
return isConnected;
}
public [Link] getCurrentConnectionState() {
if (isConnected) {
return [Link];
} else {
// Determine other states based on your logic
return [Link];
}
}
public void connectToDevice(String deviceAddress) {
if (isConnected) {
Log.i("BluetoothConnectionService", "Already connected to the
device.");
return;
}
if (!checkBluetoothPermissions()) {
Log.e("BluetoothConnectionService", "Bluetooth permissions not
granted");
requestBluetoothPermissions(); // Request permissions if not
granted
onConnectionStateChanged(false);
return;
}
try {
// Get the remote Bluetooth device
connectedDevice =
[Link]().getRemoteDevice(deviceAddress);
// Create a Bluetooth socket for communication
socket =
[Link](SPP_UUID);
// Attempt to connect to the device
[Link]();
isConnected = true;
// Notify the connection state and start reading data
new Handler([Link]()).postDelayed(() -> {
onConnectionStateChanged(true);
startReading();
}, 1000); // 1 second delay
} catch (IOException e) {
Log.e("BluetoothConnectionService", "Connection failed", e);
onConnectionStateChanged(false);
// Provide feedback to the user
showToast("Connection failed. Please check the device.");
} catch (SecurityException e) {
Log.e("BluetoothConnectionService", "Bluetooth permission
denied", e);
onConnectionStateChanged(false);
// Inform the user about the permission issue
showToast("Bluetooth permission denied. Please enable
permissions.");
} catch (Exception e) {
Log.e("BluetoothConnectionService", "Unexpected error", e);
onConnectionStateChanged(false);
// Handle any other unexpected exceptions
showToast("An unexpected error occurred: " + [Link]());
}
}
private void showToast(String message) {
// Show Toast from the main thread
new Handler([Link]()).post(() -> {
[Link](this, message, Toast.LENGTH_SHORT).show();
});
}
private boolean checkBluetoothPermissions() {
// Using `this` instead of `context` because `this` refers to the
service context
if ([Link].SDK_INT >= Build.VERSION_CODES.S) {
return [Link](this,
[Link].BLUETOOTH_CONNECT)
== PackageManager.PERMISSION_GRANTED;
} else {
return [Link](this,
[Link])
== PackageManager.PERMISSION_GRANTED;
}
}
private void requestBluetoothPermissions() {
// Requesting permissions directly from the service is not
recommended
// Permission requests should generally be handled from an Activity
or Fragment
// You can log a message or notify the UI to request permissions
}
private void startReading() {
new Thread(() -> {
byte[] buffer = new byte[1024];
int bytes;
while (isConnected) {
try {
bytes = [Link]().read(buffer);
String data = new String(buffer, 0, bytes).trim();
if (![Link]()) {
[Link](data);
float weight = [Link]();
String unit = [Link]();
boolean isStable =
[Link]();
Handler mainHandler = new
Handler([Link]());
[Link](() -> {
if (viewModel != null) {
handleWeightUpdate(weight, unit, isStable);
} else {
Log.e("BluetoothConnectionService",
"ViewModel is null");
}
sendWeightUpdate(weight, unit, isStable);
broadcastWeightData(data);
});
}
} catch (IOException e) {
Log.e("BluetoothConnectionService", "Error reading data",
e);
break;
} catch (Exception e) {
Log.e("BluetoothConnectionService", "Unexpected error",
e);
}
}
}).start();
}
private void broadcastConnectionStatus(boolean isConnected) {
Intent intent = new Intent("BLUETOOTH_CONNECTION_STATUS");
[Link]("IS_CONNECTED", isConnected);
[Link](this).sendBroadcast(intent);
}
private void broadcastWeightData(String data) {
Intent intent = new Intent("WEIGHT_DATA");
[Link]("DATA", data);
[Link](this).sendBroadcast(intent);
}
private void handleWeightUpdate(float weight, String unit, boolean
isStable) {
if (viewModel != null) {
WeightData weightData = new WeightData(weight, unit, isStable);
[Link](weightData);
} else {
Log.e("BluetoothConnectionService", "ViewModel is null in
handleWeightUpdate");
}
}
public void disconnect() {
isConnected = false;
try {
if (socket != null) {
[Link]();
}
} catch (IOException e) {
Log.e("BluetoothConnectionService", "Error closing socket", e);
}
onConnectionStateChanged(false); // Call the method here
}
@Override
public IBinder onBind(Intent intent) {
return null; // No binding is required for this service
}
@Override
public void onDestroy() {
[Link]();
// disconnect(); // Ensure the Bluetooth connection is closed
}
private void sendWeightUpdate(float weight, String unit, boolean
isStable) {
WeightData weightData = new WeightData(weight, unit, isStable);
Intent intent = new Intent("WEIGHT_UPDATE");
[Link]("WEIGHT_DATA", weightData); // WeightData is
Parcelable
[Link](this).sendBroadcast(intent);
}
private void onConnectionStateChanged(boolean isConnected) {
Handler mainHandler = new Handler([Link]());
[Link](() -> {
if (viewModel != null) {
[Link](isConnected ?
[Link] :
[Link]);
} else {
Log.e("BluetoothConnectionService", "ViewModel is null in
onConnectionStateChanged");
}
broadcastConnectionStatus(isConnected);
});
}