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
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user