nitification lisener
This commit is contained in:
1 parent
89a0671cff
commit
0ac0b4c901
8 files changed
+87
-18
No files matched your search
Generated
+13
@@ -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>
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user