made seperate BLE class
This commit is contained in:
1 parent
a6b53e3f85
commit
8e1c8d14f5
3 files changed
+160
-138
No files matched your search
@@ -0,0 +1,145 @@
|
|||||||
|
package com.example.smart_watch_android.BLE
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.bluetooth.BluetoothGatt
|
||||||
|
import android.bluetooth.BluetoothGattCallback
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
|
import android.bluetooth.BluetoothManager
|
||||||
|
import android.bluetooth.BluetoothProfile
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
|
||||||
|
class BleManager(private val context: Context) {
|
||||||
|
val deviceUUIDs = DeviceUUIDs
|
||||||
|
private var bluetoothGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
|
private var bluetoothManager: BluetoothManager? = null
|
||||||
|
private var bluetoothAdapter: BluetoothAdapter? = null
|
||||||
|
|
||||||
|
var isConnected by mutableStateOf(false)
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
|
bluetoothAdapter = bluetoothManager?.adapter
|
||||||
|
}
|
||||||
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
|
fun checkAndRequestBluetoothPermissions() {
|
||||||
|
val permissions = arrayOf(
|
||||||
|
Manifest.permission.BLUETOOTH_CONNECT,
|
||||||
|
Manifest.permission.BLUETOOTH_SCAN,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
)
|
||||||
|
|
||||||
|
// Prüfen, ob die Berechtigungen bereits erteilt wurden
|
||||||
|
val missingPermissions = permissions.filter {
|
||||||
|
ActivityCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingPermissions.isNotEmpty()) {
|
||||||
|
// Wenn Berechtigungen fehlen, frage den Nutzer danach
|
||||||
|
ActivityCompat.requestPermissions(context as Activity, missingPermissions.toTypedArray(), 101)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun connectToEsp32(deviceAddress: String) {
|
||||||
|
Log.d("ESP32_BLE", "1. connectToEsp32 gestartet mit Adresse: $deviceAddress")
|
||||||
|
if (bluetoothAdapter == null) {
|
||||||
|
Log.d("ESP32_BLE", "Fehler: Bluetooth wird von diesem Gerät nicht unterstützt!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val device = bluetoothAdapter!!.getRemoteDevice(deviceAddress)
|
||||||
|
Log.d("ESP32_BLE", "2. BluetoothDevice Objekt erfolgreich erstellt.")
|
||||||
|
|
||||||
|
val gattCallback = object : BluetoothGattCallback() {
|
||||||
|
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
||||||
|
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
||||||
|
Log.d("ESP32_BLE", "3. onConnectionStateChange aufgerufen! Status: $status, NewState: $newState")
|
||||||
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
Log.d("ESP32_BLE", "4. Verbunden! Starte discoverServices()...")
|
||||||
|
gatt.discoverServices()
|
||||||
|
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||||
|
Log.d("ESP32_BLE", "5. Getrennt worden.")
|
||||||
|
isConnected = false
|
||||||
|
|
||||||
|
gatt.close()
|
||||||
|
bluetoothGatt = null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("ESP32_BLE", "Fehler in onConnectionStateChange! Status-Code: $status")
|
||||||
|
isConnected = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
||||||
|
Log.d("ESP32_BLE", "6. onServicesDiscovered aufgerufen mit Status: $status")
|
||||||
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
|
isConnected = true
|
||||||
|
writeToEsp32("Hallo ESP32")
|
||||||
|
Log.d("ESP32_BLE", "7. Services erfolgreich gefunden! Verbindung komplett erfolgreich.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Berechtigungsprüfung
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Log.d("ESP32_BLE", "8. Berechtigung vorhanden, rufe connectGatt auf...")
|
||||||
|
bluetoothGatt = device.connectGatt(context, false, gattCallback)
|
||||||
|
} else {
|
||||||
|
Log.d("ESP32_BLE", "FEHLER: Keine BLUETOOTH_CONNECT Berechtigung erteilt!")
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.d("ESP32_BLE", "Exception gefangen: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun writeToEsp32(dataString: String) {
|
||||||
|
// Prüfen, ob die Verbindung steht und bluetoothGatt nicht null ist
|
||||||
|
val gatt = bluetoothGatt
|
||||||
|
if (gatt == null) {
|
||||||
|
Log.d("ESP32_BLE", "Fehler: Kein GATT-Objekt vorhanden (nicht verbunden).")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Service holen
|
||||||
|
val service = gatt.getService(deviceUUIDs.SERVICE_UUID)
|
||||||
|
if (service == null) {
|
||||||
|
Log.d("ESP32_BLE", "Fehler: Service UUID nicht gefunden!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Characteristic holen
|
||||||
|
val characteristic = service.getCharacteristic(deviceUUIDs.TIME_CHARACTERISTIC_UUID)
|
||||||
|
if (characteristic == null) {
|
||||||
|
Log.d("ESP32_BLE", "Fehler: Characteristic UUID nicht gefunden!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Daten in Bytes umwandeln (z.B. einen String wie "LED_ON" in UTF-8 Bytes)
|
||||||
|
val bytes = dataString.toByteArray(Charsets.UTF_8)
|
||||||
|
characteristic.value = bytes
|
||||||
|
|
||||||
|
// 4. Schreibtyp festlegen ( WRITE_TYPE_DEFAULT wartet auf Antwort vom ESP32, WRITE_TYPE_NO_RESPONSE ist schneller )
|
||||||
|
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
|
||||||
|
|
||||||
|
// 5. Berechtigung prüfen und Schreibvorgang starten
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
val success = gatt.writeCharacteristic(characteristic)
|
||||||
|
Log.d("ESP32_BLE", "Schreibvorgang gestartet: $success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.example.smart_watch_android.BLE
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
object DeviceUUIDs {
|
||||||
|
val SERVICE_UUID = UUID.fromString("791cadd7-de87-49f9-8986-94b7ae11940b")
|
||||||
|
val TIME_CHARACTERISTIC_UUID = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e02")
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
package com.example.smart_watch_android
|
package com.example.smart_watch_android
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Application
|
|
||||||
import android.bluetooth.BluetoothDevice
|
|
||||||
import android.bluetooth.BluetoothGatt
|
import android.bluetooth.BluetoothGatt
|
||||||
import android.bluetooth.BluetoothGattCallback
|
import android.bluetooth.BluetoothGattCallback
|
||||||
|
import android.bluetooth.BluetoothGattCharacteristic
|
||||||
import android.bluetooth.BluetoothManager
|
import android.bluetooth.BluetoothManager
|
||||||
import android.bluetooth.BluetoothProfile
|
import android.bluetooth.BluetoothProfile
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -17,156 +16,26 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import com.example.smart_watch_android.ui.theme.SmartWatchAndroidTheme
|
import com.example.smart_watch_android.BLE.BleManager
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
private var bluetoothGatt: BluetoothGatt? = null
|
val bleManager = BleManager(context = this)
|
||||||
|
|
||||||
var isConnected by mutableStateOf(false)
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val SERVICE_UUID = UUID.fromString("791cadd7-de87-49f9-8986-94b7ae11940b")
|
|
||||||
private val CHARACTERISTIC_UUID = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e02")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
checkAndRequestBluetoothPermissions()
|
bleManager.init()
|
||||||
|
bleManager.checkAndRequestBluetoothPermissions()
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
ConnectCircleScreen(
|
ConnectCircleScreen(
|
||||||
isConnected = isConnected,
|
isConnected = bleManager.isConnected,
|
||||||
onConnectClick = {
|
onConnectClick = {
|
||||||
Log.d("ESP32_BLE", "Button wurde gedrückt!")
|
Log.d("ESP32_BLE", "Button wurde gedrückt!")
|
||||||
connectToEsp32("10:BD:A3:8F:01:0E")
|
bleManager.connectToEsp32("10:BD:A3:8F:01:0E")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@RequiresApi(Build.VERSION_CODES.S)
|
|
||||||
private fun checkAndRequestBluetoothPermissions() {
|
|
||||||
val permissions = arrayOf(
|
|
||||||
Manifest.permission.BLUETOOTH_CONNECT,
|
|
||||||
Manifest.permission.BLUETOOTH_SCAN,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION
|
|
||||||
)
|
|
||||||
|
|
||||||
// Prüfen, ob die Berechtigungen bereits erteilt wurden
|
|
||||||
val missingPermissions = permissions.filter {
|
|
||||||
ActivityCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
|
|
||||||
if (missingPermissions.isNotEmpty()) {
|
|
||||||
// Wenn Berechtigungen fehlen, frage den Nutzer danach
|
|
||||||
ActivityCompat.requestPermissions(this, missingPermissions.toTypedArray(), 101)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun connectToEsp32(deviceAddress: String) {
|
|
||||||
Log.d("ESP32_BLE", "1. connectToEsp32 gestartet mit Adresse: $deviceAddress")
|
|
||||||
val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
|
||||||
val bluetoothAdapter = bluetoothManager.adapter
|
|
||||||
if (bluetoothAdapter == null) {
|
|
||||||
Log.d("ESP32_BLE", "Fehler: Bluetooth wird von diesem Gerät nicht unterstützt!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
val device = bluetoothAdapter.getRemoteDevice(deviceAddress)
|
|
||||||
Log.d("ESP32_BLE", "2. BluetoothDevice Objekt erfolgreich erstellt.")
|
|
||||||
|
|
||||||
val gattCallback = object : BluetoothGattCallback() {
|
|
||||||
@RequiresPermission(Manifest.permission.BLUETOOTH_CONNECT)
|
|
||||||
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
|
||||||
Log.d("ESP32_BLE", "3. onConnectionStateChange aufgerufen! Status: $status, NewState: $newState")
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
|
||||||
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
|
||||||
Log.d("ESP32_BLE", "4. Verbunden! Starte discoverServices()...")
|
|
||||||
gatt.discoverServices()
|
|
||||||
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
|
||||||
Log.d("ESP32_BLE", "5. Getrennt worden.")
|
|
||||||
isConnected = false
|
|
||||||
|
|
||||||
gatt.close()
|
|
||||||
bluetoothGatt = null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d("ESP32_BLE", "Fehler in onConnectionStateChange! Status-Code: $status")
|
|
||||||
isConnected = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
|
|
||||||
Log.d("ESP32_BLE", "6. onServicesDiscovered aufgerufen mit Status: $status")
|
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
|
||||||
isConnected = true
|
|
||||||
writeToEsp32("Hallo ESP32")
|
|
||||||
Log.d("ESP32_BLE", "7. Services erfolgreich gefunden! Verbindung komplett erfolgreich.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Berechtigungsprüfung
|
|
||||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
Log.d("ESP32_BLE", "8. Berechtigung vorhanden, rufe connectGatt auf...")
|
|
||||||
bluetoothGatt = device.connectGatt(this, false, gattCallback)
|
|
||||||
} else {
|
|
||||||
Log.d("ESP32_BLE", "FEHLER: Keine BLUETOOTH_CONNECT Berechtigung erteilt!")
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.d("ESP32_BLE", "Exception gefangen: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeToEsp32(dataString: String) {
|
|
||||||
// Prüfen, ob die Verbindung steht und bluetoothGatt nicht null ist
|
|
||||||
val gatt = bluetoothGatt
|
|
||||||
if (gatt == null) {
|
|
||||||
Log.d("ESP32_BLE", "Fehler: Kein GATT-Objekt vorhanden (nicht verbunden).")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Service holen
|
|
||||||
val service = gatt.getService(SERVICE_UUID)
|
|
||||||
if (service == null) {
|
|
||||||
Log.d("ESP32_BLE", "Fehler: Service UUID nicht gefunden!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Characteristic holen
|
|
||||||
val characteristic = service.getCharacteristic(CHARACTERISTIC_UUID)
|
|
||||||
if (characteristic == null) {
|
|
||||||
Log.d("ESP32_BLE", "Fehler: Characteristic UUID nicht gefunden!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Daten in Bytes umwandeln (z.B. einen String wie "LED_ON" in UTF-8 Bytes)
|
|
||||||
val bytes = dataString.toByteArray(Charsets.UTF_8)
|
|
||||||
characteristic.value = bytes
|
|
||||||
|
|
||||||
// 4. Schreibtyp festlegen ( WRITE_TYPE_DEFAULT wartet auf Antwort vom ESP32, WRITE_TYPE_NO_RESPONSE ist schneller )
|
|
||||||
characteristic.writeType = android.bluetooth.BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
|
|
||||||
|
|
||||||
// 5. Berechtigung prüfen und Schreibvorgang starten
|
|
||||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
val success = gatt.writeCharacteristic(characteristic)
|
|
||||||
Log.d("ESP32_BLE", "Schreibvorgang gestartet: $success")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user