I’m developing an Android app where I need to block and then repost notifications. My app successfully blocks notifications, but when I try to repost them, they don’t appear in the status bar. I have added logging to confirm that the repost method is called and executed without errors.
Here are the relevant parts of my code:
MyNotificationListener class:
package com.blissio_ai_frontend
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import android.util.Log
class MyNotificationListener : NotificationListenerService() {
companion object {
var BLOCK_ALL: Boolean = false
val blockedAppPackages: MutableList<String> = mutableListOf()
private const val TAG = "MyNotificationListener"
val blockedNotifications: MutableList<StatusBarNotification> = mutableListOf()
private lateinit var context: Context
fun initialize(context: Context) {
this.context = context
}
}
override fun onNotificationPosted(sbn: StatusBarNotification) {
val notification: Notification = sbn.notification
val packageName: String = sbn.packageName
val title: CharSequence? = notification.extras.getCharSequence(Notification.EXTRA_TITLE)
val text: CharSequence? = notification.extras.getCharSequence(Notification.EXTRA_TEXT)
Log.d(TAG, "Notification from: $packageName, Title: $title, Text: $text")
if (BLOCK_ALL) {
cancelAllNotifications()
Log.d(TAG, "All notifications blocked")
storeBlockedNotification(sbn)
} else {
if (blockedAppPackages.contains(packageName)) {
cancelNotification(sbn.key)
Log.d(TAG, "Notification from $packageName blocked")
storeBlockedNotification(sbn)
}
}
}
override fun onNotificationRemoved(sbn: StatusBarNotification) {
Log.d(TAG, "Notification removed: ${sbn.packageName}")
}
private fun storeBlockedNotification(sbn: StatusBarNotification) {
blockedNotifications.add(sbn)
}
fun getBlockedNotifications(): String {
return blockedNotifications.joinToString(separator = "n") { sbn ->
val packageName = sbn.packageName
val title = sbn.notification.extras.getCharSequence(Notification.EXTRA_TITLE)
val text = sbn.notification.extras.getCharSequence(Notification.EXTRA_TEXT)
"Package: $packageName, Title: $title, Text: $text"
}
}
fun repostBlockedNotifications() {
Log.d(TAG, "Reposting blocked notifications")
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"default_channel",
"Default Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
notificationManager.createNotificationChannel(channel)
}
blockedNotifications.forEach { sbn ->
val originalNotification = sbn.notification
val repostedNotificationBuilder = Notification.Builder(context)
.setContentTitle(originalNotification.extras.getCharSequence(Notification.EXTRA_TITLE))
.setContentText(originalNotification.extras.getCharSequence(Notification.EXTRA_TEXT))
.setWhen(originalNotification.`when`)
.setShowWhen(true)
.setChannelId(originalNotification.channelId ?: "default_channel")
.setSmallIcon(context.applicationInfo.icon)
.setPriority(Notification.PRIORITY_HIGH)
.setAutoCancel(true)
val repostedNotification = repostedNotificationBuilder.build()
Log.d(TAG, "Reposting notification with ID: ${System.currentTimeMillis().toInt()}")
notificationManager.notify(System.currentTimeMillis().toInt(), repostedNotification)
}
}
}
and this is my notification module :
package com.blissio_ai_frontend
import android.util.Log
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.provider.Settings
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
class NotificationModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val context: ReactApplicationContext = reactContext
init {
MyNotificationListener.initialize(context)
}
override fun getName(): String {
return "NotificationModule"
}
@ReactMethod
fun openNotificationSettings() {
val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
@ReactMethod
fun setBlockAllNotifications(block: Boolean) {
MyNotificationListener.BLOCK_ALL = block
}
@ReactMethod
fun blockNotificationsForApp(packageName: String, block: Boolean) {
if (block) {
MyNotificationListener.blockedAppPackages.add(packageName)
} else {
MyNotificationListener.blockedAppPackages.remove(packageName)
}
}
@ReactMethod
fun setDoNotDisturb(enable: Boolean, promise: Promise) {
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (notificationManager.isNotificationPolicyAccessGranted) {
notificationManager.setInterruptionFilter(
if (enable) NotificationManager.INTERRUPTION_FILTER_NONE
else NotificationManager.INTERRUPTION_FILTER_ALL
)
promise.resolve(true)
} else {
promise.reject("PERMISSION_DENIED", "Notification policy access is not granted")
}
}
@ReactMethod
fun getBlockedNotifications(promise: Promise) {
val listener = MyNotificationListener()
val blockedNotifications = listener.getBlockedNotifications()
Log.d("NotificationModule", "Blocked Notifications: $blockedNotifications")
promise.resolve(blockedNotifications)
}
@ReactMethod
fun repostBlockedNotifications(promise: Promise) {
try {
val listener = MyNotificationListener()
listener.repostBlockedNotifications()
promise.resolve(true)
} catch (e: Exception) {
Log.e("NotificationModule", "Error reposting notifications", e)
promise.reject("ERROR_REPOSTING", "Failed to repost notifications")
}
}
}
this is my javascript code
import React, {useState} from 'react';
import {View, Button, StyleSheet, Text, ScrollView} from 'react-native';
import {NativeModules} from 'react-native';
const {NotificationModule} = NativeModules;
const openNotificationAccessSettings = () => {
NotificationModule.openNotificationAccessSettings();
};
const setDoNotDisturb = (enable: boolean) => {
NotificationModule.setBlockAllNotifications(enable);
console.log('Navigated to notification settings for Facebook.');
};
const getBlockedNotifications = async () => {
try {
const notifications = await NotificationModule.getBlockedNotifications();
console.log('Blocked notifications:', notifications);
// Repost the blocked notifications
const repostResult = await NotificationModule.repostBlockedNotifications();
console.log('Repost result:', repostResult);
} catch (error) {
console.error('Error retrieving or reposting blocked notifications', error);
}
};
const NotificationSettings: React.FC = () => {
const [blockedNotifications, setBlockedNotifications] = useState<string>('');
return (
<View style={styles.container}>
<Button
title="Open Notification Access Settings"
onPress={openNotificationAccessSettings}
/>
<Button
title="Enable Do Not Disturb"
onPress={() => setDoNotDisturb(true)}
/>
<Button
title="Disable Do Not Disturb"
onPress={() => setDoNotDisturb(false)}
/>
<Button
title="Get Blocked Notifications"
onPress={getBlockedNotifications}
/>
<ScrollView style={styles.scrollView}>
<Text>{blockedNotifications}</Text>
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
scrollView: {
marginTop: 20,
padding: 10,
width: '100%',
},
});
export default NotificationSettings;
this is my logs in android
15:02:44.022 11367 11367 D MyNotificationListener: All notifications blocked
06-30 15:02:44.040 11367 11367 D MyNotificationListener: Notification removed: com.facebook.katana
06-30 15:02:49.500 11367 11453 D MyNotificationListener: Reposting blocked notifications
06-30 15:02:49.503 11367 11453 D MyNotificationListener: Reposting notification with ID: 1756651103
06-30 15:12:37.700 11367 11367 D MyNotificationListener: Notification from: com.google.android.setupwizard, Title: اتمام راهاندازی Xperia™, Text: کپی کردن دادهها، و چند دلیل دیگر
06-30 15:12:37.701 11367 11367 D MyNotificationListener: All notifications blocked
Sajad Mardani is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.