Фон
Я нашел приложение, которое каким-то образом скрывает уведомления о хедз-апе, включая даже текущие уведомления (используемые передними службами), называемые NCleaner.
Мне было интересно, как это работает.
Эта проблема
Информация о том, как контролировать уведомления других приложений, не так много. Только из текущего приложения, и по какой-то причине я не смог отменить текущее уведомление, но мне удалось отменить нормальный.
Что я нашел
Я нашел этот пример, показывающий, как отслеживать уведомления. После поиска в документах NotificationListenerService, я также нашел, как отменить определенные уведомления других приложений.
Однако он не работает для текущих уведомлений.
Для тестирования обычных уведомлений я просто отправил себе электронное письмо или написал что-то в приложении PushBullet через свой компьютер.
Для тестирования текущих уведомлений я установил и запустил приложение для свободного времени ( здесь), которое показывает текущее уведомление прямо в начале приложения, начиная с Android O. Фактически, оно может даже скрывать уведомления ОС, USB-соединения и отладки (просто подключите устройство к ПК через USB)...
Здесь код, который я сделал, на основе образца, чтобы отменить все уведомления, которые он получает:
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) {}
}
проявляются:
<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"))
}
}
}
Вопросы
- Почему мой код не может удалить текущие уведомления?
- Почему приложение, которое я нашел, может это сделать? Что оно делает?
- Сколько всего этого API предоставляет с точки зрения уведомлений? Глядя на документы, кажется, что он может многое сделать: читать уведомления, увольнять их, получать информацию о них, но я не могу найти другие возможности: возможно ли изменить уведомление? Изменить приоритет? Чтобы избежать его уведомления об уведомлении и просто быть в ящике уведомлений? Возможно ли инициировать действие уведомления?