scan+connection

This commit is contained in:
leo 2022-05-10 15:53:11 +02:00
parent 30e8352a2c
commit 7653acb442
Signed by: leo
GPG Key ID: 0DD993BFB2B307DB
5 changed files with 191 additions and 3 deletions

View File

@ -7,7 +7,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.example.co2sense_app" applicationId "com.example.co2sense_app"
minSdk 21 minSdk 26
targetSdk 31 targetSdk 31
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@ -30,7 +30,7 @@ android {
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1' 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' implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.ext:junit:1.1.3'

View File

@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.co2sense_app"> package="com.example.co2sense_app">
<uses-feature android:name="android.software.companion_device_setup"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -19,5 +22,4 @@
</intent-filter> </intent-filter>
</activity> </activity>
</application> </application>
</manifest> </manifest>

View File

@ -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<String> 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;
}
}

View File

@ -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);
}
}

View File

@ -1,14 +1,37 @@
package com.example.co2sense_app; package com.example.co2sense_app;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
BLEDevice sensor;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); 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);
}
} }