wake-up-neo.com

Wie storniere ich eine laufende Benachrichtigung über eine andere App?

Hintergrund

Ich habe eine App gefunden, die Heads-Up-Benachrichtigungen, auch laufende Benachrichtigungen (die von Vordergrunddiensten verwendet werden), unter NCleaner versteckt.

Ich habe mich gefragt, wie so etwas funktioniert.

Das Problem

Es gibt nicht viele Informationen darüber, wie Sie die Benachrichtigungen anderer Apps steuern. Nur von der aktuellen App und aus irgendeinem Grund konnte ich eine laufende Benachrichtigung nicht abbrechen, aber es ist mir gelungen, eine normale abzubrechen.

Was ich gefunden habe

Ich habe dieses Beispiel gefunden das zeigt, wie man Benachrichtigungen überwacht. Nach der Suche in den Dokumenten zu NotificationListenerService habe ich auch herausgefunden, wie Sie bestimmte Benachrichtigungen über andere Apps abbrechen können.

Es funktioniert jedoch nicht für laufende Benachrichtigungen.

Zum Testen normaler Benachrichtigungen schickte ich mir einfach eine E-Mail oder schrieb etwas über meinen PC in die PushBullet-App.

Zum Testen laufender Benachrichtigungen habe ich meine Freizeit-App installiert und ausgeführt ( hier ), die eine laufende Benachrichtigung zu Beginn der App anzeigt, beginnend mit Android O. , kann es sogar die Benachrichtigungen des Betriebssystems, des USB-Anschlusses und des Debugging verbergen (einfach das Gerät über USB an den PC anschließen) ...

Hier ist der Code, den ich basierend auf dem Beispiel erstellt habe, um alle Benachrichtigungen abzubrechen, die er erhält:

NotificationListenerExampleService.kt

class NotificationListenerExampleService : NotificationListenerService() {

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        Log.d("AppLog", "sbn:" + sbn.toString())
        cancelNotification(sbn.key)
    }

    override fun onListenerConnected() {
        super.onListenerConnected()
        Log.d("AppLog", "onListenerConnected")
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification) {}
}

Manifest:

<application
  Android:allowBackup="true" Android:icon="@mipmap/ic_launcher" Android:label="@string/app_name" Android:supportsRtl="true" Android:theme="@style/AppTheme"
  tools:ignore="AllowBackup,GoogleAppIndexingWarning">
  <activity Android:name=".MainActivity">
    <intent-filter>
      <action Android:name="Android.intent.action.MAIN"/>

      <category Android:name="Android.intent.category.LAUNCHER"/>
    </intent-filter>
  </activity>

  <service
    Android:name=".NotificationListenerExampleService" Android:label="@string/service_label" Android:permission="Android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
      <action Android:name="Android.service.notification.NotificationListenerService"/>
    </intent-filter>
  </service>
</application>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val isNotificationServiceEnabled: Boolean
        get() {
            val pkgName = packageName
            val flat = Settings.Secure.getString(contentResolver, "enabled_notification_listeners"")
            if (!TextUtils.isEmpty(flat)) {
                val names = flat.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                for (i in names.indices) {
                    val cn = ComponentName.unflattenFromString(names[i])
                    if (cn != null) {
                        if (TextUtils.equals(pkgName, cn.packageName)) {
                            return true
                        }
                    }
                }
            }
            return false
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (!isNotificationServiceEnabled) {
            startActivity(Intent("Android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
        }
    }

}

Die Fragen

  1. Wie kommt es, dass mein Code laufende Benachrichtigungen nicht entfernen kann?
  2. Wie kommt die gefundene App dazu? Was tut es?
  3. Wie viel bietet diese API in Bezug auf Benachrichtigungen? Wenn Sie sich die Dokumente ansehen, scheint es eine Menge zu tun: Benachrichtigungen lesen, abweisen, alle Arten von Informationen darüber abrufen, ... Aber ich kann keine anderen Funktionen finden: Kann ich eine Benachrichtigung ändern? Um seine Priorität zu ändern? Um zu vermeiden, dass es eine Heads-Up-Benachrichtigung ist und nur in der Benachrichtigungsschublade ist? Ist es möglich, eine Aktion einer Benachrichtigung auszulösen?
12

Ich habe diesen Code für die Erstellung von Benachrichtigungen verwendet. Es hat Titel, Text, Symbol, contentAction als Broadcast Message. Es reicht für die Beantwortung Ihrer Fragen, hoffe ich.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val notChannel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT)
            notManager.createNotificationChannel(notChannel)
        }

        val builder = NotificationCompat.Builder([email protected], CHANNEL_ID)

        val contentIntent = Intent(NOT_ACTION)
        contentIntent.putExtra(EXTRA_NOT_ID, notificationId)

        val contentAction = PendingIntent.getBroadcast([email protected], NOT_REQ_CODE, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT)

        builder.setContentTitle("Notification $notificationId")
                .setContentText("Awesome text for $notificationId notification")
                .setContentIntent(contentAction)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .setDefaults(NotificationCompat.DEFAULT_ALL)

        NotificationManagerCompat
                .from([email protected])
                .notify(notificationId++, builder.build())

1. Können Sie eine Benachrichtigungsaktion auslösen?

Ja, das kannst du. Sie können Notification von StatusBarNotification und dann PendingIntents für Aktionen abrufen und diese verwenden.
Zum Beispiel möchte ich ein contentAction der Benachrichtigung auslösen

override fun onNotificationPosted(sbn: StatusBarNotification) {
    super.onNotificationPosted(sbn)

    Log.d(TAG, "Gotcha notification from ${sbn.packageName}")

    if (sbn.packageName == TARGET_PACKAGE) {
        val contentIntent = sbn.notification.contentIntent
        contentIntent.send()
    }
}

Dieser Code löst das Senden von Broadcast-Nachricht aus. ABER es ignoriert eine .setAutoCancel(true) der Benachrichtigung, so dass Sie es manuell behandeln müssen

    if (sbn.packageName == TARGET_PACKAGE) {
        val contentIntent = sbn.notification.contentIntent
        contentIntent.send()
        if (sbn.notification.flags and Notification.FLAG_AUTO_CANCEL != 0) {
            cancelNotification(sbn.key)
        }
    }

2. Wie NCleaner laufende Benachrichtigungen abbricht?

Die erste Möglichkeit, die mir einfällt, ist die Verwendung von NotificationListenerService.snoozeNotification wie folgt

if (sbn.packageName == TARGET_PACKAGE) {
        snoozeNotification(sbn.key, Long.MAX_VALUE - System.currentTimeMillis())
}

Ich bin zu 99% sicher, dass NCLeaner diesen Code verwendet. Weil diese Funktion für Pre-O-Geräte nicht unterstützt wird.

Hinweis. Sie können Long.MAX_VALUE nicht einfach verwenden, die Benachrichtigung wird für ein paar Sekunden abgespeckt und erscheint dann erneut. Getestet auf Pixel 2 8.1.

3. Können Sie eine vorhandene Benachrichtigung ändern?

Nein, das geht nicht. Nur eine Benachrichtigungsinhaber-App kann sie ändern.

P.S.

Ich habe auch versucht, Grenzen durch Nachdenken durch versteckte Methoden und Felder von NotificationManager und NotificationListenerService zu überwinden. Das Ergebnis aller Versuche ist:

Ursache: Java.lang.SecurityException: Beim Aufruf von uid 10210 wurde das Paket com.ns.notificationsender angegeben, dessen Eigentümer uid 10211 ist

Daher muss Ihre App ein System sein, oder Root kann dabei helfen, erfolgreich zu sein. Aber ich habe kein solches Gerät.

2
Ufkoku