Compare commits

...
1 Commits
Author SHA1 Message Date
lash404 0ac0b4c901 nitification lisener 2026-11-03 15:06:10 +01:00
8 changed files with 87 additions and 18 deletions

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DeviceTable">
<option name="columnSorters">
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
</ColumnSorterState>
</list>
</option>
</component>
</project>
+8
View File
@@ -17,6 +17,14 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.SmartWatchAndroid"> android:theme="@style/Theme.SmartWatchAndroid">
<service
android:name=".Notification.MyNotificationListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@@ -9,17 +9,12 @@ 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
import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission import androidx.annotation.RequiresPermission
import androidx.compose.ui.platform.LocalContext
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityCompat.startActivityForResult
import com.example.smart_watch_android.MainViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -139,33 +134,44 @@ object BLEManager{
Log.d("BLE_DEBUG", "Permission BLUETOOTH_CONNECT error!") Log.d("BLE_DEBUG", "Permission BLUETOOTH_CONNECT error!")
} }
} }
fun writeToEsp32(context: Context, dataString: String, SERVICE_UUID: UUID?, CHARACTERISTIC_UUID: UUID?) { fun writeToEsp32(context: Context, dataString: String?, SERVICE_UUID: UUID?, CHARACTERISTIC_UUID: UUID?) {
val gatt = bluetoothGatt val gatt = bluetoothGatt
if (gatt == null) { if (gatt == null) {
Log.d("ESP32_BLE", "error: no GATT-Objekt existing (not connected).") Log.d("ESP32_BLE", "Error: No GATT object existing (not connected).")
return
}
if (dataString == null) {
Log.d("ESP32_BLE", "Error: Data string is null.")
return return
} }
val service = gatt.getService(SERVICE_UUID) val service = gatt.getService(SERVICE_UUID)
if (service == null) { if (service == null) {
Log.d("ESP32_BLE", "error: Service UUID not found!") Log.d("ESP32_BLE", "Error: Service UUID not found!")
return return
} }
val characteristic = service.getCharacteristic(CHARACTERISTIC_UUID) val characteristic = service.getCharacteristic(CHARACTERISTIC_UUID)
if (characteristic == null) { if (characteristic == null) {
Log.d("ESP32_BLE", "error: Characteristic UUID not found!") Log.d("ESP32_BLE", "Error: Characteristic UUID not found!")
return return
} }
val bytes = dataString.toByteArray(Charsets.UTF_8) if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
characteristic.value = bytes Log.d("ESP32_BLE", "Error: BLUETOOTH_CONNECT permission not granted.")
return
}
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT characteristic.value = dataString.toByteArray(Charsets.UTF_8)
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) { characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
val success = gatt.writeCharacteristic(characteristic)
Log.d("ESP32_BLE", "started writing: $success") val success = gatt.writeCharacteristic(characteristic)
if (success) {
Log.d("ESP32_BLE", "Successfully started writing: $dataString")
} else {
Log.d("ESP32_BLE", "Failed to start writing (gatt busy or invalid state).")
} }
} }
fun syncTime(context: Context) { fun syncTime(context: Context) {
@@ -189,7 +195,7 @@ object BLEManager{
writeToEsp32( writeToEsp32(
context = context, context = context,
dataString ="$formattedDate", dataString = formattedDate,
SERVICE_UUID = deviceUUIDs.SERVICE_UUID, SERVICE_UUID = deviceUUIDs.SERVICE_UUID,
CHARACTERISTIC_UUID = deviceUUIDs.CHAR_DATE_UUID) CHARACTERISTIC_UUID = deviceUUIDs.CHAR_DATE_UUID)
} }
@@ -7,4 +7,7 @@ object DeviceUUIDs {
val CHAR_MESSAGE_UUID: UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e01") val CHAR_MESSAGE_UUID: UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e01")
val CHAR_TIME_UUID:UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e02") val CHAR_TIME_UUID:UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e02")
val CHAR_DATE_UUID:UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e03") val CHAR_DATE_UUID:UUID? = UUID.fromString("3e4eac5b-eaa2-4e0c-a705-dcac4f606e03")
val CHAR_NOTIF_APP_UUID:UUID? = UUID.fromString("9ff3d4a9-2082-424d-bf34-8dfaf752ff90")
val CHAR_NOTIF_TITLE_UUID:UUID? = UUID.fromString("9ff3d4a9-2082-424d-bf34-8dfaf752ff91")
val CHAR_NOTIF_TEXT_UUID: UUID? = UUID.fromString("9ff3d4a9-2082-424d-bf34-8dfaf752ff92")
} }
@@ -2,6 +2,8 @@ package com.example.smart_watch_android
import android.Manifest import android.Manifest
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@@ -18,6 +20,8 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.example.smart_watch_android.BLE.BLEManager import com.example.smart_watch_android.BLE.BLEManager
import com.example.smart_watch_android.BLE.DeviceUUIDs
import com.example.smart_watch_android.Notification.MyNotificationListener
import com.example.smart_watch_android.Screens.AppNavigation import com.example.smart_watch_android.Screens.AppNavigation
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@@ -0,0 +1,21 @@
package com.example.smart_watch_android.Notification
import android.content.Intent
import android.service.notification.StatusBarNotification
import android.util.Log
import android.service.notification.NotificationListenerService
class MyNotificationListener : NotificationListenerService() {
override fun onNotificationPosted(sbn: StatusBarNotification?) {
super.onNotificationPosted(sbn)
val packageName = sbn?.packageName
val extras = sbn?.notification?.extras
val title = extras?.getString("android.title")
val text = extras?.getString("android.text")
Log.d("NotificationListener", "App: $packageName | Title: $title | Text: $text")
}
override fun onNotificationRemoved(sbn: StatusBarNotification?) {
super.onNotificationRemoved(sbn)
}
}
@@ -1,6 +1,8 @@
package com.example.smart_watch_android.Screens package com.example.smart_watch_android.Screens
import android.Manifest import android.Manifest
import android.content.Intent
import android.provider.Settings
import androidx.annotation.RequiresPermission import androidx.annotation.RequiresPermission
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -51,6 +53,10 @@ fun AppNavigation(viewModel: MainViewModel) {
onDisconnectClicked = { onDisconnectClicked = {
BLEManager.disconnectEsp32(context = context) BLEManager.disconnectEsp32(context = context)
}, },
onNotificationListnerClicked = {
val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
context.startActivity(intent)
}
) )
} }
} }
@@ -12,7 +12,6 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@@ -29,7 +28,8 @@ import com.example.smart_watch_android.MainViewModel
@Composable @Composable
fun ControlPanelScreen( fun ControlPanelScreen(
viewModel: MainViewModel, viewModel: MainViewModel,
onDisconnectClicked: () -> Unit onDisconnectClicked: () -> Unit,
onNotificationListnerClicked: () -> Unit
) { ) {
val context = LocalContext.current val context = LocalContext.current
var textInput by remember { mutableStateOf("") } var textInput by remember { mutableStateOf("") }
@@ -93,5 +93,13 @@ fun ControlPanelScreen(
) { ) {
Text("Disconnect") Text("Disconnect")
} }
Button(
onClick = onNotificationListnerClicked,
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFFE53935)),
modifier = Modifier.fillMaxWidth()
) {
Text("Notification Listener")
}
} }
} }