From 7653acb442d39b652aa95e024ec0c57c74dd10e1 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 10 May 2022 15:53:11 +0200 Subject: [PATCH] scan+connection --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 4 +- .../com/example/co2sense_app/BLEDevice.java | 150 ++++++++++++++++++ .../com/example/co2sense_app/CO2Sensor.java | 13 ++ .../example/co2sense_app/MainActivity.java | 23 +++ 5 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/example/co2sense_app/BLEDevice.java create mode 100644 app/src/main/java/com/example/co2sense_app/CO2Sensor.java 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