made seperate BLE class

This commit is contained in:
Gitea committed 2026-10-16 20:48:39 +02:00
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
import android.Manifest
import android.app.Application
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
import android.content.Context
@@ -17,156 +16,26 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
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 com.example.smart_watch_android.ui.theme.SmartWatchAndroidTheme
import java.util.UUID
import com.example.smart_watch_android.BLE.BleManager
class MainActivity : ComponentActivity() {
private var bluetoothGatt: BluetoothGatt? = null
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")
val bleManager = BleManager(context = this)
@RequiresApi(Build.VERSION_CODES.S)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkAndRequestBluetoothPermissions()
bleManager.init()
bleManager.checkAndRequestBluetoothPermissions()
enableEdgeToEdge()
setContent {
ConnectCircleScreen(
isConnected = isConnected,
isConnected = bleManager.isConnected,
onConnectClick = {
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")
}
}
}