Arturo Pineda
Arturo Pineda

Reputation: 81

How to access notification channels for another Android app?

I want to create a function that calls the notification channel settings for another app. I don't know the channel IDs for the other app. Is there a way to do that?

Upvotes: 4

Views: 1733

Answers (4)

Ivan Zolotaryov
Ivan Zolotaryov

Reputation: 11

You can access notification channels of other apps using NotificationListenerService, which is in-built in SDK. After registering the service and giving notification access permission (using Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")), it is possible to just call something like the following method:

private List<NotificationChannel> getChannels() {
    final var ranking = getCurrentRanking();
    final var channelsList = new ArrayList<NotificationChannel>();

    for (var notification : getActiveNotifications()) {
        final var currentRanking = new Ranking();
        ranking.getRanking(notification.getKey(), currentRanking);
        channelsList.add(currentRanking.getChannel());
    }
    return channelsList;
}

Upvotes: 0

hacker1024
hacker1024

Reputation: 3678

This can be done through reflection. Note that more hidden APIs are blocked with every Android release, so this is not a long-term solution.

First, add the android.permission.STATUS_BAR_SERVICE permission to AndroidManifest.xml. My IDE warns that this is a system app permission, but my device (running Xiaomi's MIUI 12.5, Android 11) allows it.

<manifest ...>
    <uses-permission android:name="android.permission.STATUS_BAR_SERVICE"
                     tools:ignore="ProtectedPermissions"/>
    ...
</manifest>

Now, any app's channels can be accessed:

// Retreive an instance of the INotificationManager service using the
// hidden NotificationManager.getService static method.
val sINM = NotificationManager::class.java.getMethod("getService").invoke(null)

// Find the INotificationManager.getNotificationChannelsForPackage method.
val getNotificationChannelsForPackageMethod =
    sINM::class.java.getMethod(
        "getNotificationChannelsForPackage",
        java.lang.String::class.java,
        Integer.TYPE,
        java.lang.Boolean.TYPE,
    )

// Retreive information about an app.
val applicationInfo = packageManager.getApplicationInfo("com.example", 0)

// Retreive a ParceledListSlice of the app's NotificationChannel objects.
// The boolean is the "includeDeleted" parameter.
val channelsSlice = getNotificationChannelsForPackageMethod.invoke(
    sINM,
    applicationInfo.packageName,
    applicationInfo.uid,
    false,
)

// Retreive the channels in the form of an ArrayList<NotificationChannel>.
val channels = channelsSlice::class.java.getMethod("getList")
    .invoke(channelsSlice) as ArrayList<NotificationChannel>

AOSP references:

NotificationManager.java

INotificationManager.aidl

BaseParceledListSlice.java

Upvotes: 1

Floern
Floern

Reputation: 33904

You cannot access the notification channels of another app, neither what channels there are nor what their settings are.

The only thing you can do is to open the notification settings overview of another app, given its package name (Facebook for example):

Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
        .putExtra(Settings.EXTRA_APP_PACKAGE, "com.facebook.katana");
startActivity(intent);

Upvotes: 3

Gunavant Patel
Gunavant Patel

Reputation: 1541

No, You can not handle other app Notification Channel because every change has id and without id System can not get that channel. According to my knowledge we can not get notification channel ids of other app.

Upvotes: 0

Related Questions