How can I programmatically open/close notifications in Android?
Asked Answered
C

7

34

I've searched everywhere, but can't find anything in the SDK or on Google on how to do this. I know it's possible because all the custom launchers are able to do it via a button press (LauncherPro, ADW, etc).

Thanks.

Cornered answered 17/2, 2011 at 13:9 Comment(2)
Does getSystemService("statusbar") return an object?Anagram
yes it does. But I can't map it to StatusBarManager because it's not a part of the public API. So, right now I just have it as type "Object". What can I do to it to make it useable?Cornered
C
50

You can programmatically close the notification drawer by broadcasting an ACTION_CLOSE_SYSTEM_DIALOGS intent.

This causes "temporary system dialogs" to be dismissed. From the documentation:

Some examples of temporary system dialogs are the notification window-shade and the recent tasks dialog.

This doesn't require any permissions, and has apparently been available since Android 1.0.

The following code works for me on a Nexus 4 running Android 5.0:

Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(closeIntent);
Chantress answered 30/7, 2015 at 23:51 Comment(6)
This should be the accepted answer. The solution in the accepted answer didn't work for me.Thissa
Via adb: adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGSLadonnalady
What about opening the notification drawer?Generatrix
This is deprecated and doesn't work in Android 12Heiner
Sadly not usable in Android 12 anymore: developer.android.com/about/versions/12/behavior-changes-allTetramethyldiarsine
anyone knows how to do that in Android 12 or higher (the documation it's not clear too much)Millman
S
27

The answer from Ashwin works for Android versions below 4.2.2 (i.e. below version 17). In 4.2.2, the "expand" method was changed to "expandNotificationsPanel". If you don't use that method name for 4.2.2 and above, you will get a Null Pointer Exception. So the code should be:

Object sbservice = getSystemService( "statusbar" );
Class<?> statusbarManager = Class.forName( "android.app.StatusBarManager" );
Method showsb;
if (Build.VERSION.SDK_INT >= 17) {
    showsb = statusbarManager.getMethod("expandNotificationsPanel");
}
else {
    showsb = statusbarManager.getMethod("expand");
}
showsb.invoke( sbservice );

And appropriate permission should be added to AndroidManifest.

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

Obviously, this is not part of the published API, so this is not guaranteed to work in the future and many people would advise against doing this.

Shelled answered 23/3, 2013 at 1:50 Comment(8)
Oh, and also in version 4.2.2, you can use the method "expandSettingsPanel" to directly display the new settings panel with the toggles that was made available starting in version 4.2.2.Shelled
I get InvocationTargetExceptionBorisborja
I had to add the permission to the testing project as wellBorisborja
I had to invoke collapsePanels on Android 4.3. Here's the source code: android.googlesource.com/platform/frameworks/base.git/+/…Dessiatine
You must add the following permission to run this code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />Plunk
This doesn't seem to work on Samsung devices with Lollipop or higher. Am I wrong ?Edulcorate
@Edulcorate On Samsung Lollipop, I'm getting java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) ... Caused by: java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL... anyone has any workaround methods?Adrell
@kevinze: I am getting same error as your error. Do you solve it?Nosology
A
15

Yes you can add this code to wherever you want it to execute

Object sbservice = getSystemService( "statusbar" );
Class<?> statusbarManager = Class.forName( "android.app.StatusBarManager" );
Method showsb = statusbarManager.getMethod( "expand" );
showsb.invoke( sbservice );

And add this permission

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
Aston answered 4/7, 2012 at 6:18 Comment(1)
Is there any way to make the transition faster?Forbearance
G
5

Sadly there's still no official API (requested here, please consider starring), but for now, you can use this code, which I've generalized from all of the answers I've found :

// based on https://gist.github.com/XinyueZ/7bad2c02be425b350b7f 
// requires permission: "android.permission.EXPAND_STATUS_BAR"
@SuppressLint("WrongConstant", "PrivateApi")
fun setExpandNotificationDrawer(context: Context, expand: Boolean) {
    try {
        val statusBarService = context.getSystemService("statusbar")
        val methodName =
                if (expand)
                    if (Build.VERSION.SDK_INT >= 17) "expandNotificationsPanel" else "expand"
                else
                    if (Build.VERSION.SDK_INT >= 17) "collapsePanels" else "collapse"
        val statusBarManager: Class<*> = Class.forName("android.app.StatusBarManager")
        val method: Method = statusBarManager.getMethod(methodName)
        method.invoke(statusBarService)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

EDIT: also adb command, which might be an alternative workaround (taken from here) :

collapse:

adb shell service call statusbar 2

expand:

adb shell service call statusbar 1
Generatrix answered 2/7, 2018 at 8:43 Comment(0)
B
4

How can I programmatically open/close notifications in Android?

What you want cannot be done using the Android SDK.

I know it's possible because all the cuustome launchers are able to do it via a button press (LauncherPro, ADW, etc).

All of the "custom launchers" are bypassing the SDK, using a variation on the technique that @Yoni Samlan proposed in another answer to your question. Things that are not part of the SDK can be removed by device manufacturers, replaced by the core Android team in future releases, etc.

I would argue that what you want should be possible via the SDK; otherwise, it really limits alternative home screen implementations. However, what you and I want does not count for all that much.

Betimes answered 17/2, 2011 at 14:28 Comment(4)
OK, is there any "hacky" way to get the notifications to close? For example are there any flags I can set when launching an intent that would force the notification bar to get closed? Or anything else like that?Cornered
@user496854: Not that I am aware of.Betimes
@com, is there still no way to do this?Imperialism
@whoabackoff: There is still nothing in the Android SDK for this.Betimes
D
2

Christopher Orr's answer works great for closing the notification drawer.

You can use AccessibilityServices to programmatically show the notifications or quick settings by calling:

Decrial answered 17/11, 2018 at 3:38 Comment(0)
F
-3

Here's the showNotifications method from Android's Launcher:

private void showNotifications() {
    final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);
    if (statusBar != null) {
        statusBar.expand();
    }
}

(which, as Robby indicated, is the "statusbar" system service).

Forestation answered 17/2, 2011 at 14:13 Comment(4)
This is not part of the Android SDK.Betimes
this doesn't work because there is no StatusBarManager class in the public APICornered
Yup. CommonsWare is right; I was just poking through the source code and not the related SDKs, sorry.Forestation
This is likely dead now, but Fede's UberMusic does just this! There are actually two permissions STATUS_BAR and EXPAND_STATUS_BAR that might be of use.Georgetown

© 2022 - 2024 — McMap. All rights reserved.