Как я могу программно открывать/закрывать уведомления в Android?

Я искал везде, но не могу найти ничего в SDK или в Google о том, как это сделать. Я знаю, что это возможно, потому что все пользовательские программы запуска могут сделать это нажатием кнопки (LauncherPro, ADW и т. д.).

Спасибо.


person user496854    schedule 17.02.2011    source источник
comment
Возвращает ли getSystemService (строка состояния) объект?   -  person Robby Pond    schedule 17.02.2011
comment
Да, это так. Но я не могу сопоставить его с StatusBarManager, потому что он не является частью общедоступного API. Итак, прямо сейчас у меня это просто тип Object. Что я могу сделать с ним, чтобы сделать его пригодным для использования?   -  person user496854    schedule 17.02.2011


Ответы (7)


Вы можете программно закрыть панель уведомлений, передав ACTION_CLOSE_SYSTEM_DIALOGS намерение.

Это приводит к тому, что «временные системные диалоги» закрываются. Из документации:

Некоторыми примерами временных системных диалогов являются шторка окна уведомлений и диалог недавних задач.

Это не требует никаких разрешений и, по-видимому, доступно с Android 1.0.

Следующий код работает для меня на Nexus 4 под управлением Android 5.0:

Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(closeIntent);
person Christopher Orr    schedule 30.07.2015
comment
Это помогло мне. Спасибо. - person Andrew; 29.08.2015
comment
Это должен быть принятый ответ. Решение в принятом ответе не сработало для меня. - person 0ne_Up; 28.09.2018
comment
Через adb: adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS - person jonleighton; 14.11.2018
comment
Как насчет открытия ящика уведомлений? - person android developer; 13.03.2019

ответ от Ashwin работает для версий Android ниже 4.2.2 (т.е. ниже версии 17). В версии 4.2.2 метод «расширить» был изменен на «расширить панель уведомлений». Если вы не используете это имя метода для 4.2.2 и выше, вы получите исключение нулевого указателя. Итак, код должен быть:

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 );

И соответствующее разрешение должно быть добавлено к AndroidManifest.

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

Очевидно, что это не является частью опубликованного API, поэтому не гарантируется, что это будет работать в будущем, и многие люди не советуют этого делать.

person Jonathan    schedule 23.03.2013
comment
Да, а также в версии 4.2.2 вы можете использовать метод expandSettingsPanel для прямого отображения новой панели настроек с переключателями, которые стали доступны, начиная с версии 4.2.2. - person Jonathan; 23.03.2013
comment
Я получаю InvocationTargetException - person Kirill Kulakov; 16.09.2013
comment
Мне также пришлось добавить разрешение на тестовый проект. - person Kirill Kulakov; 16.09.2013
comment
Мне пришлось вызвать свернуть панели на Android 4.3. Вот исходный код: android.googlesource.com/platform/frameworks/base.git/+/ - person Maragues; 10.10.2013
comment
Вы должны добавить следующее разрешение для запуска этого кода ‹uses-permission android:name=android.permission.EXPAND_STATUS_BAR /› - person Alauddin Ansari; 24.10.2014
comment
Похоже, это не работает на устройствах Samsung с Lollipop или выше. Я ошибаюсь ? - person guy.gc; 19.10.2015
comment
@guy.gc В Samsung Lollipop я получаю java.lang.reflect.InvocationTargetException в java.lang.reflect.Method.invoke(Native Method) ... Вызвано: java.lang.SecurityException: Отказ в доступе: get/ установить настройку для пользователя, который запрашивает запуск от имени пользователя -2, но звонит от пользователя 0; для этого требуется android.permission.INTERACT_ACROSS_USERS_FULL... у кого-нибудь есть обходные пути? - person Kevin Lee; 27.02.2016
comment
@kevinze: я получаю ту же ошибку, что и ваша ошибка. Вы решаете это? - person user3051460; 20.10.2016

Да, вы можете добавить этот код туда, где хотите, чтобы он выполнялся.

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

И добавьте это разрешение

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
person Ashwin Singh    schedule 04.07.2012
comment
Есть ли способ сделать переход быстрее? - person vault; 15.03.2016

Как я могу программно открывать/закрывать уведомления в Android?

То, что вы хотите, невозможно сделать с помощью Android SDK.

Я знаю, что это возможно, потому что все пользовательские программы запуска могут сделать это нажатием кнопки (LauncherPro, ADW и т. д.).

Все «пользовательские пусковые установки» обходят SDK, используя вариант метода, предложенного @Yoni Samlan в другом ответе на ваш вопрос. Вещи, которые не являются частью SDK, могут быть удалены производителями устройств, заменены основной командой Android в будущих выпусках и т. д.

Я бы сказал, что то, что вы хотите, должно быть возможным через SDK; в противном случае это действительно ограничивает альтернативные реализации домашнего экрана. Однако то, чего мы с тобой хотим, не имеет большого значения.

person CommonsWare    schedule 17.02.2011
comment
Хорошо, есть ли какой-нибудь хакерский способ закрыть уведомления? Например, есть ли какие-либо флаги, которые я могу установить при запуске намерения, которые заставят панель уведомлений закрыться? Или что-то еще в этом роде? - person user496854; 17.02.2011
comment
@ user496854: Не то, чтобы я знал об этом. - person CommonsWare; 17.02.2011
comment
@com, до сих пор нет способа сделать это? - person whoabackoff; 14.05.2012
comment
@whoabackoff: В Android SDK по-прежнему ничего для этого нет. - person CommonsWare; 15.05.2012

К сожалению, до сих пор нет официального API (запрошено здесь), но для теперь вы можете использовать этот код, который я обобщил из всех ответов, которые я нашел:

// 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()
    }
}
person android developer    schedule 02.07.2018

Ответ Кристофера Орра отлично подходит для закрытия панели уведомлений.

Вы можете использовать AccessibilityServices для программного отображения уведомлений или быстрых настроек, вызвав:

person Eric    schedule 17.11.2018

Вот метод showNotifications из Android Launcher:

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

(которая, как указал Робби, является системной службой «строки состояния»).

person Yoni Samlan    schedule 17.02.2011
comment
Это не часть Android SDK. - person CommonsWare; 17.02.2011
comment
это не работает, потому что в общедоступном API нет класса StatusBarManager - person user496854; 17.02.2011
comment
Ага. CommonsWare прав; Я просто просматривал исходный код, а не соответствующие SDK, извините. - person Yoni Samlan; 17.02.2011
comment
Это, вероятно, уже мертво, но UberMusic Феде делает именно это! На самом деле есть два разрешения STATUS_BAR и EXPAND_STATUS_BAR, которые могут быть полезны. - person Tom; 09.08.2011