diff --git a/app/build.gradle b/app/build.gradle
index 2354e2a..ca1eef9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,7 +7,7 @@ android {
defaultConfig {
applicationId "com.example.co2sense_app"
- minSdk 21
+ minSdk 26
targetSdk 31
versionCode 1
versionName "1.0"
@@ -30,7 +30,7 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
- implementation 'com.google.android.material:material:1.5.0'
+ implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cb9c5cb..57d5186 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
-
\ No newline at end of file
diff --git a/app/src/main/java/com/example/co2sense_app/BLEDevice.java b/app/src/main/java/com/example/co2sense_app/BLEDevice.java
new file mode 100644
index 0000000..48bbcc9
--- /dev/null
+++ b/app/src/main/java/com/example/co2sense_app/BLEDevice.java
@@ -0,0 +1,150 @@
+package com.example.co2sense_app;
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.companion.AssociationRequest;
+import android.companion.BluetoothDeviceFilter;
+import android.companion.CompanionDeviceManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.activity.result.ActivityResultCaller;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.RequiresApi;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import java.util.NoSuchElementException;
+
+public class BLEDevice {
+ private static final int REQUEST_BT_PERMISSION = 16535;
+ private static final int REQUEST_ENABLE_BT = 16536;
+ private static final int SELECT_DEVICE_REQUEST_CODE = 16537;
+ private static final int REQUEST_BT_CONNECT_PERMISSION = 16538;
+
+ private final Activity activity;
+ private boolean startPairingOnBTStart;
+
+ private BluetoothGatt bluetoothGatt;
+ private BluetoothDevice device;
+ private final ActivityResultLauncher requestPermissionLauncher;
+
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ BLEDevice(Activity activity) {
+ this.activity = activity;
+ requestPermissionLauncher = ((ActivityResultCaller) activity).registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> connect());
+ }
+
+ public void startBT() {
+ Context context = activity.getApplicationContext();
+ BluetoothManager bluetoothManager = ContextCompat.getSystemService(context, BluetoothManager.class);
+ if (bluetoothManager == null)
+ throw new NoSuchElementException("No Bluetooth manager found");
+ BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
+ if (bluetoothAdapter == null)
+ throw new NoSuchElementException("No Bluetooth adapter found");
+
+ if (bluetoothAdapter.isEnabled()) {
+ if (startPairingOnBTStart) pair();
+ } else {
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
+ activity.requestPermissions(new String[]{Manifest.permission.BLUETOOTH}, REQUEST_BT_PERMISSION);
+ return;
+ }
+ activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ }
+ }
+
+ protected void pair() {
+ BluetoothDeviceFilter deviceFilter = new BluetoothDeviceFilter.Builder()
+ //.setNamePattern(Pattern.compile("My device"))
+ //.addServiceUuid(new ParcelUuid(new UUID(0x123abcL, -1L)), null)
+ .build();
+ AssociationRequest pairingRequest = new AssociationRequest.Builder()
+ .addDeviceFilter(deviceFilter)
+ //.setSingleDevice(true)
+ .build();
+
+ CompanionDeviceManager deviceManager = (CompanionDeviceManager) activity.getSystemService(Context.COMPANION_DEVICE_SERVICE);
+ deviceManager.associate(pairingRequest, new CompanionDeviceManager.Callback() {
+ @Override
+ public void onDeviceFound(IntentSender chooserLauncher) {
+ try {
+ activity.startIntentSenderForResult(chooserLauncher, SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0
+ );
+ } catch (IntentSender.SendIntentException e) {
+ Log.e("MainActivity", "Failed to send intent");
+ }
+ }
+
+ @Override
+ public void onFailure(CharSequence error) {
+ Log.e("pair", (String) error);
+ }
+ }, null);
+ }
+
+ @SuppressLint("MissingPermission")
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ protected void connect() {
+ /*if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH);
+ Log.d("bt", "no perm");
+ return;
+ }*/
+ Log.d("bt", device.toString());
+ bluetoothGatt = device.connectGatt(activity, false, new BluetoothGattCallback() {
+ @Override
+ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+ if (newState == BluetoothProfile.STATE_CONNECTED) {
+ Log.d("bt", "connected");
+ } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
+ Log.d("bt", "disconnected");
+ }
+ }
+ });
+ }
+
+ @SuppressLint("MissingPermission")
+ protected void disconnect(){
+ bluetoothGatt.close();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_ENABLE_BT:
+ if(resultCode != Activity.RESULT_OK) startBT();
+ else if(startPairingOnBTStart) pair();
+ break;
+ case SELECT_DEVICE_REQUEST_CODE:
+ Log.d("bt", "device selected");
+ if (data != null) {
+ Log.d("bt", "data ok");
+ BluetoothDevice deviceToPair = data.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE);
+ if (deviceToPair != null) {
+ this.device = deviceToPair;
+ connect();
+ }
+ }
+ break;
+ }
+ }
+
+ public void startPairingOnBTStart(boolean status) {
+ startPairingOnBTStart = status;
+ }
+}
diff --git a/app/src/main/java/com/example/co2sense_app/CO2Sensor.java b/app/src/main/java/com/example/co2sense_app/CO2Sensor.java
new file mode 100644
index 0000000..d02dbbd
--- /dev/null
+++ b/app/src/main/java/com/example/co2sense_app/CO2Sensor.java
@@ -0,0 +1,13 @@
+package com.example.co2sense_app;
+
+import android.app.Activity;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+public class CO2Sensor extends BLEDevice {
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ CO2Sensor(Activity activity) {
+ super(activity);
+ }
+}
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 597d23d..53e8fff 100644
--- a/app/src/main/java/com/example/co2sense_app/MainActivity.java
+++ b/app/src/main/java/com/example/co2sense_app/MainActivity.java
@@ -1,14 +1,37 @@
package com.example.co2sense_app;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
+import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
+ BLEDevice sensor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
+
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ sensor = new BLEDevice(this);
+ sensor.startPairingOnBTStart(true);
+ sensor.startBT();
+ sensor.pair();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.S)
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ sensor.onActivityResult(requestCode, resultCode, data);
+ }
}
\ No newline at end of file