diff --git a/app/src/main/java/com/example/co2sense_app/BLEDevice.java b/app/src/main/java/com/example/co2sense_app/BLEDevice.java index 7b0ec82..969c9a6 100644 --- a/app/src/main/java/com/example/co2sense_app/BLEDevice.java +++ b/app/src/main/java/com/example/co2sense_app/BLEDevice.java @@ -29,7 +29,10 @@ import androidx.annotation.RequiresApi; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import java.util.EnumMap; +import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; import java.util.NoSuchElementException; import java.util.PriorityQueue; import java.util.Queue; @@ -57,6 +60,18 @@ public abstract class BLEDevice { LinkedList commandQueue = new LinkedList<>(); boolean commandLock=false; + private boolean newStatusAvailable; + + public enum connectionState{ERROR, STARTING_BLUETOOTH, SCANNING, CONNECTING, CONNECTED, DISCOVERING_SERVICES, DISCOVERED_CHAR, REGISTERING_NOTIFS, READING_DATA, IDLE, DISCONNECTED}; + private EnumMap stateText = new EnumMap<>(connectionState.class); + + public connectionState currentState = connectionState.ERROR; + + public interface onStatusChangedCallback{ + void onStatusChanged(connectionState newState); + } + + private onStatusChangedCallback statusChangedCallback; @RequiresApi(api = Build.VERSION_CODES.S) BLEDevice(Activity activity) { @@ -68,11 +83,24 @@ public abstract class BLEDevice { if (bluetoothManager == null) throw new NoSuchElementException("No Bluetooth manager found"); bluetoothAdapter = bluetoothManager.getAdapter(); + + stateText.put(connectionState.ERROR, activity.getString(R.string.status_text_error)); + stateText.put(connectionState.STARTING_BLUETOOTH, activity.getString(R.string.status_text_starting_bluetooth)); + stateText.put(connectionState.SCANNING, activity.getString(R.string.status_text_scanning)); + stateText.put(connectionState.CONNECTING, activity.getString(R.string.status_text_connecting)); + stateText.put(connectionState.CONNECTED, activity.getString(R.string.status_text_connected)); + stateText.put(connectionState.DISCOVERING_SERVICES, activity.getString(R.string.status_text_discovering_services)); + stateText.put(connectionState.DISCOVERED_CHAR, activity.getString(R.string.status_text_discovered_char)); + stateText.put(connectionState.REGISTERING_NOTIFS, activity.getString(R.string.status_text_reg_notif)); + stateText.put(connectionState.READING_DATA, activity.getString(R.string.status_text_reading_data)); + stateText.put(connectionState.DISCONNECTED, activity.getString(R.string.status_text_disconnected)); + stateText.put(connectionState.IDLE, activity.getString(R.string.status_text_idle)); } @RequiresApi(api = Build.VERSION_CODES.S) public void startBT() { Log.d("bt", "startBT"); + setStatus(connectionState.STARTING_BLUETOOTH); if (bluetoothAdapter == null) throw new NoSuchElementException("No Bluetooth adapter found"); @@ -96,6 +124,7 @@ public abstract class BLEDevice { Log.d("bt", "no perm"); return; }*/ + setStatus(connectionState.CONNECTING); Log.d("bt", device.toString()); BLEDevice mainClass = this; bluetoothGatt = device.connectGatt(activity, false, new BluetoothGattCallback() { @@ -103,9 +132,12 @@ public abstract class BLEDevice { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { Log.d("bt", "connected"); + setStatus(connectionState.CONNECTED); bluetoothGatt.discoverServices(); + setStatus(connectionState.DISCOVERING_SERVICES); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { Log.d("bt", "disconnected"); + setStatus(connectionState.DISCONNECTED); connect(); } } @@ -114,9 +146,11 @@ public abstract class BLEDevice { public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.d("bt", "onServicesDiscovered: finished"); + setStatus(connectionState.DISCOVERED_CHAR); mainClass.onServicesDiscovered(); } else { Log.w("bt", "onServicesDiscovered received: " + status); + setStatus(connectionState.ERROR); } } @@ -200,9 +234,11 @@ public abstract class BLEDevice { protected void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status){ eventCallback.onDescriptorRead(gatt, descriptor, status); + setStatus(connectionState.IDLE); } protected void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){ eventCallback.onCharacteristicRead(gatt, characteristic, status); + setStatus(connectionState.IDLE); } @RequiresApi(api = Build.VERSION_CODES.S) @@ -230,6 +266,7 @@ public abstract class BLEDevice { Log.d("BLE_device", "startScan: "); BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(callback); + setStatus(connectionState.SCANNING); } @RequiresApi(api = Build.VERSION_CODES.S) @@ -248,6 +285,7 @@ public abstract class BLEDevice { @Override public void run() { bluetoothGatt.writeDescriptor(descr); + setStatus(connectionState.REGISTERING_NOTIFS); } }); runNextCommand(); @@ -261,6 +299,7 @@ public abstract class BLEDevice { @Override public void run() { bluetoothGatt.readCharacteristic(charact); + setStatus(connectionState.READING_DATA); } }); runNextCommand(); @@ -271,6 +310,25 @@ public abstract class BLEDevice { if(commandQueue.size()==0) return; commandLock=true; Log.d("bt", "runNextCommand: "); - commandQueue.poll().run(); + Runnable command = commandQueue.poll(); + command.run(); + } + + void setStatus(connectionState newState){ + currentState = newState; + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + statusChangedCallback.onStatusChanged(newState); + } + }); + } + + void registerStatusCallback(onStatusChangedCallback callback){ + statusChangedCallback = callback; + } + + String getStatusText(connectionState state){ + return stateText.get(state); } } diff --git a/app/src/main/java/com/example/co2sense_app/MainActivity.java b/app/src/main/java/com/example/co2sense_app/MainActivity.java index 11cbd34..ee168c7 100644 --- a/app/src/main/java/com/example/co2sense_app/MainActivity.java +++ b/app/src/main/java/com/example/co2sense_app/MainActivity.java @@ -17,6 +17,7 @@ import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.widget.TextView; public class MainActivity extends AppCompatActivity { CO2Sensor sensor; @@ -41,6 +42,14 @@ public class MainActivity extends AppCompatActivity { sensor = new CO2Sensor(this); + TextView statusText = findViewById(R.id.status); + sensor.registerStatusCallback(new BLEDevice.onStatusChangedCallback(){ + @Override + public void onStatusChanged(BLEDevice.connectionState newState){ + statusText.setText(sensor.getStatusText(newState)); + } + }); + if(targetDeviceMAC != null) { sensor.setDeviceFromMAC(targetDeviceMAC); sensor.startConnectOnBTStart(true); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index adf2eb1..53db44e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,4 +5,15 @@ erreur select com.example.co2sense_app.SHARED_PREF_MAIN + Error + starting bluetooth + scanning + connecting + connected + discovering characteristics + registering notifs + disconnected + reading data + waiting + discovering services \ No newline at end of file