Android compose `NotificationListenerService.onNotificationPosted` 永远不会被调用

问题描述 投票:0回答:1

我正在尝试向 Kotlin android compose 项目添加通知侦听器:

我的

AndroidManigest.xml

    <application>
        <!-- ... -->
        <service
            android:name=".MyNotificationListenerService"
            android:exported="false"
            android:foregroundServiceType="specialUse"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">

            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
            <property
                android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
                android:value="explanation_for_special_use" />
        </service>

    </application>

    <uses-permission
        android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

我的

MainActivity.kt

class MainActivity : ComponentActivity() {

    private lateinit var serviceIntent: Intent

    private fun isServiceRunningInForeground(): Boolean {
        val manager = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager
        @Suppress("DEPRECATION")
        for (service in manager.getRunningServices(Int.MAX_VALUE)) {
            if (MyNotificationListenerService::class.java.name == service.service.className) {
                if (service.foreground) {
                    return true
                }
            }
        }
        return false
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        serviceIntent = Intent(this, MyNotificationListenerService::class.java)
        Log.d("NB", "MainActivity.onCreate")

        setContent {
            MyNotificationListenerTheme {
                var isServiceRunning by remember { mutableStateOf(isServiceRunningInForeground()) }

                Scaffold(
                    floatingActionButton = {
                        FloatingActionButton(
                            onClick = {
                                if (isServiceRunning) {
                                    stopService(serviceIntent)
                                } else {
                                    if (!NotificationManagerCompat.getEnabledListenerPackages(this)
                                            .contains(
                                                packageName
                                            )
                                    ) {
                                        startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
                                    }

                                    startForegroundService(
                                        serviceIntent
                                    )
                                }
                                isServiceRunning = !isServiceRunning
                            }
                        ) {
                            Icon(
                                imageVector = if (isServiceRunning) Icons.Default.Close else Icons.Default.PlayArrow,
                                contentDescription = if (isServiceRunning) "Pause" else "Play"
                            )
                        }
                    }
                ) { innerPadding ->
                    Surface(
                        modifier = Modifier.padding(innerPadding),
                        color = MaterialTheme.colorScheme.background
                    ) {
                        // Your UI content
                    }
                }
            }
        }
    }
}

我的

MyNotificationListenerService.kt

class MyNotificationListenerService : NotificationListenerService() {

    private val channelId = "MyNotificationListenerService"

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        startForeground(1, getNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
        Log.d("NB", "MyNotificationListenerService.onCreate")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("NB", "MyNotificationListenerService.onStartCommand")
        return START_STICKY
    }

    private fun createNotificationChannel() {
        val serviceChannel = NotificationChannel(
            channelId,
            "My Notification Listener Service Channel",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager = getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(serviceChannel)
    }

    private fun getNotification(): Notification {
        return Notification.Builder(this, channelId)
            .setContentTitle("Running...")
            .build()
    }

    override fun onBind(intent: Intent?): IBinder? {
        Log.d("NB", "MyNotificationListenerService.onBind")
        return super.onBind(intent)
    }

    override fun onDestroy() {
        Log.d("NB", "MyNotificationListenerService.onDestroy")
        return super.onDestroy()
    }

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        val text = sbn.notification?.extras?.getString("android.text");
        Log.d("NB", "MyNotificationListenerService.onNotificationPosted - text: $text")
        super.onNotificationPosted(sbn)
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification) {
        // Optionally handle notification removal
    }

    override fun onListenerConnected() {
        Log.d("NB", "MyNotificationListenerService.onListenerConnected")
    }
}

当我按“播放”时,我确实收到了日志:

MainActivity.onCreate
MyNotificationListenerService.onCreate
MyNotificationListenerService.onStartCommand

但是当我的手机收到通知时,

MyNotificationListenerService.onNotificationPosted
没有被呼叫。

我错过了什么?

android kotlin android-jetpack-compose notificationlistenerservice
1个回答
0
投票

正如评论中Mike M.所建议的,这不是你自己开始的。

用户必须手动将您的应用程序启用为监听器,然后您的Service将由系统自动启动。

可以将用户引导到屏幕,以便他们使用

startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
启用它。

删除启动服务的逻辑和所有前台相关代码使其工作:

AndroidManifest.xml

    <application>
        <!-- ... -->
        <service
            android:name=".MyNotificationListenerService"
            android:exported="false"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>

    </application>

    <uses-permission
        android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission" />

MainActivity.kt

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MyNotificationListenerTheme {
                var isServiceRunning by remember { mutableStateOf(isServiceRunningInForeground()) }

                Scaffold { innerPadding ->
                    Surface(
                        modifier = Modifier.padding(innerPadding),
                        color = MaterialTheme.colorScheme.background
                    ) {
                        // Your UI content
                    }
                }
            }
        }
    }
}

MyNotificationListenerService.kt

class MyNotificationListenerService : NotificationListenerService() {

    override fun onCreate() {
        super.onCreate()
        Log.d("NB", "MyNotificationListenerService.onCreate")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("NB", "MyNotificationListenerService.onStartCommand")
        return START_STICKY
    }

    override fun onBind(intent: Intent?): IBinder? {
        Log.d("NB", "MyNotificationListenerService.onBind")
        return super.onBind(intent)
    }

    override fun onDestroy() {
        Log.d("NB", "MyNotificationListenerService.onDestroy")
        return super.onDestroy()
    }

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        val text = sbn.notification?.extras?.getString("android.text");
        Log.d("NB", "MyNotificationListenerService.onNotificationPosted - text: $text")
        super.onNotificationPosted(sbn)
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification) {
        // Optionally handle notification removal
    }

    override fun onListenerConnected() {
        Log.d("NB", "MyNotificationListenerService.onListenerConnected")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.