2013-08-15 4 views
41

Я добавляю панель уведомлений в системную панель, используя библиотеку NotificationCompat. В этом уведомлении есть две кнопки действий. Кроме того, свойство AutoCancel() в уведомлении имеет значение true.Нажав кнопку «Android», не закройте окно уведомлений

При нажатии кнопок действий система настроена на запуск IntentService, который вызывает NotificationManager.cancel(NOTIFICATION_ID), а затем запускает операцию в новой задаче.
Проблема в том, что хотя этот вызов удаляет уведомление из лотка, он не сбрасывает ящик. Вызывается вызванная деятельность за ящиком.

Может кто-то пролить некоторый свет на то, какой специальный код необходимо закрыть, кроме отмены уведомления?

спасибо.

+1

Вы когда-нибудь находили решение для этого? –

+6

Нет. Просто некоторые хаки, чтобы использовать отражение и развернуть, свернуть строку состояния. По-видимому, если ваше ожидающее намерение содержит намерение, которое разрешает действие, ящик автоматически сбрасывается. Однако, если ваш ожидающий намерение обертывает BroadcastReceiver или Service, лоток уведомлений сохраняет свое (расширенное) состояние. – Aster

ответ

0

Система андроидов сбрасывает ящик уведомлений для вас, когда вы нажимаете на уведомление и запускаете действие или трансляцию. Я не думаю, что есть какой-либо программный способ закрыть ящик уведомлений вашим кодом. Я предлагаю вам проверить намерения, которые вы передаете строителю уведомлений, и убедиться, что им даны правильные ссылки. Я думаю, что что-то внутри диспетчера уведомлений android блокируется из-за намерения, которое вы предоставляете. До сих пор я не видел, чтобы ящик уведомлений оставался открытым после того, как действие было инициировано из уведомления. Просто интересно узнать, имеет ли ваша целевая деятельность полупрозрачная область, где видна предыдущая активность, если это тогда, я предлагаю вам сделать фон полностью непрозрачным (без прозрачной/полупрозрачной области). Может быть, это предотвратит запуск стартовой панели андроида для завершения последовательности останова и, таким образом, не позволяет запускать, чтобы закрыть ящик уведомлений для вас. Надеюсь, я смог тебе помочь. Всего наилучшего.

1

Хотя я полностью понимаю, что ответ Soumyajyoti должен быть правильным ... это на самом деле не ...

я использую

Intent CR = new Intent(CRCODE); 
PendingIntent.getBroadcast(getApplicationContext(), MY_ID, CR, 0); 

в макете RemoteView для постоянного уведомления ...

Я могу заверить вас, что он не закрывает ящик, но увольняет намерение и рисует активность за открытым ящиком, а также выполняет другие задачи, которые я назначил моему приемнику ...

я испытал как getActivity и GetService (ни один из которых будет работать в моем обстоятельстве, мне нужно стрелять несколько намерений onRecieve) и оба из них закрыть выдвижной ящик ...

Я знаю, что это не ответ, но когда и если я найду его, я отчитаюсь об этом, чтобы отредактировать это ...

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

сумасшедшая мысль, перечисленная выше, работает ... начинает деятельность с PendingIntent. getActivity и использовать его для ретрансляции трансляций или других намерений, затем закончить сам ... эффект не является прямым, но незаметным для конечного пользователя

9

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

Прежде чем использовать расширенные уведомления, действие по умолчанию в уведомлении загрузки файла состояло в том, чтобы запустить активность VIEW в файле. Цель VIEW была завернута намерением Chooser. Я не мог использовать ожидающее намерение для намерения Chooser непосредственно из уведомления, потому что Chooser выйдет из строя, если не будет активности для просмотра типа файла. Таким образом, у меня был BroadcastReceiver, который запустил бы намерение Chooser.

С расширенными уведомлениями я решил изменить уведомление о загрузке файлов, поэтому действие по умолчанию - показать активность сведений о файле, с кнопками действий для просмотра и отправки. Как отмечено пользователем2536953, запуск широковещательного приемника из уведомления не закрывает ящик уведомлений. Основываясь на его информации о том, что активность закрывает ящик, я изменил свой вещательный приемник на NotificationActivity без какого-либо пользовательского интерфейса.

Как указано в этом сообщении How to dismiss Android notification after action has been clicked, еще одна проблема заключается в том, что вы должны вручную отменить свое уведомление, когда пользователь нажимает кнопку действия. Уведомление отменяется автоматически для действия по умолчанию. Я также добавил код в NotificationActivity, чтобы справиться с этим.

Строительства расширенного уведомления с видом и отправить кнопок:

NotificationCompat.Builder builder = new NotificationCompat.Builder(m_context).setAutoCancel(true); 

    final PendingIntent contentIntent = DownloadedFileIntentUtils.buildPendingItemDetailIntent(m_context, item); 
     builder.setContentIntent(contentIntent); 

    PendingIntent viewIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_VIEW, 
       m_context.getString(R.string.action_open), uri, MimeTypeUtil.getMimeType(item), id); 
    builder.addAction(R.drawable.actionbar_open_with, m_context.getString(R.string.action_open), viewIntent); 

    PendingIntent sendIntent = DownloadedFileIntentUtils.buildNotificationActionIntent(m_context, Intent.ACTION_SEND, 
       m_context.getString(R.string.action_send), uri, MimeTypeUtil.getMimeType(item), id); 
    builder.addAction(R.drawable.actionbar_share, m_context.getString(R.string.action_send), sendIntent); 

    builder.setTicker(title) 
    .setContentTitle(title) 
    .setContentText(text) 
    .setSmallIcon(R.drawable.notification_download); 
    .setStyle(new NotificationCompat.BigTextStyle().bigText(text)); 

    getNotificationManager().notify(id, builder.build()); 

Строительство намерения начать деятельность с помощью кнопок действий уведомления:

public static PendingIntent buildNotificationActionIntent(Context context, String action, String actionTitle, Uri uri, 
     String mimeType, int notificationId) { 
    // Build the file action intent (e.g. VIEW or SEND) that we eventually want to start. 
    final Intent fileIntent = buildFileActionIntent(action, actionTitle, uri, mimeType); 

    // Build the intent to start the NotificationActivity. 
    final Intent notificationIntent = new Intent(context, NotificationActivity.class); 
    // This flag must be set on activities started from a notification. 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    // Pass the file action and notification id to the NotificationActivity. 
    notificationIntent.putExtra(Intent.EXTRA_INTENT, fileIntent); 
    notificationIntent.putExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, notificationId); 

    // Return a pending intent to pass to the notification manager. 
    return PendingIntent.getActivity(context, s_intentCode.getAndIncrement(), notificationIntent, PendingIntent.FLAG_ONE_SHOT); 
} 

public static Intent buildFileActionIntent(String action, String actionTitle, 
     Uri uri, String mimeType) { 
    Intent intent = new Intent(action); 
    intent.addCategory(Intent.CATEGORY_DEFAULT); 

    if (action.equals(Intent.ACTION_SEND)) { 
     intent.putExtra(Intent.EXTRA_STREAM, uri); 
     intent.setType(mimeType); 
    } else { 
     intent.setDataAndType(uri, mimeType); 
    } 

    intent.putExtra(Intent.EXTRA_TITLE, actionTitle); 

    // Grant read permission on the file to other apps without declared permission. 
    int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION; 
    intent.setFlags(flags); 

    return intent; 
} 

Notification деятельность без какого-либо UI:

public class NotificationActivity extends Activity { 
private final static Logger s_logger = LogUtil.getLogger(NotificationActivity.class); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent intent = getIntent(); 

    // Cancel the notification that initiated this activity. 
    // This is required when using the action buttons in expanded notifications. 
    // While the default action automatically closes the notification, the 
    // actions initiated by buttons do not. 
    int notificationId = intent.getIntExtra(IIntentCode.INTENT_EXTRA_NOTIFICATION_ID, -1); 
    if (notificationId != -1) { 
     NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     manager.cancel(notificationId); 
    } 

    // If there is an activity to handle the action, start the file action. 
    if (DownloadedFileIntentUtils.verifyActivityIsAvailable(this, fileActionIntent, false)) { 
      fileActionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      DownloadedFileIntentUtils.startFileActionActivity(this, fileActionIntent); 
    } 

    // Finish activity. 
    finish(); 
} 

public static void startFileActionActivity(Context context, Intent fileActionIntent) { 
    // Start chooser intent. 
    Intent chooser = Intent.createChooser(fileActionIntent, fileActionIntent.getStringExtra(Intent.EXTRA_TITLE)); 

    // Copy the flags from fileActionIntent to chooser intent. 
    // FileActionExecutor must set FLAG_ACTIVITY_NEW_TASK on the intent passed to startActivity 
    // because the flag is required when starting an activity from a context that is not an activity. 
    chooser.addFlags(fileActionIntent.getFlags()); 

    context.startActivity(chooser); 
} 

Не забудьте добавить NotificationActivity в AndroidManifest.xml.

+0

Большое спасибо! –

+1

Мне нужно было установить android: taskAffinity = "" в NotificationActivity, иначе он начал MainActivity, если он существовал в backstack –

+0

http://stackoverflow.com/questions/42527534/pending-action-expand-notification-on- нажмите «Пожалуйста, у меня есть вопрос –

36

Если действие в виде эфира или услугу, но вы собираетесь за ящик уведомление разрушаться, вы должны транслировать android.intent.action.CLOSE_SYSTEM_DIALOGS от вашего OnReceive. Это приведет к ручному закрытию ящика.

+26

sendBroadcast (новый Intent (Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); – goodhyun

+2

Метод sendBroadcast может быть найден внутри объекта контекста. –

+0

Я добавил эти строки в свой BroadcastReceiver перед вызовом context.startActivity (myIntent) Intent it = new Intent (Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.sendBroadcast (it); –

Смежные вопросы