2013-08-15 18 views
41

Dodaję powiadomienie do paska systemowego przy użyciu biblioteki NotificationCompat. To powiadomienie ma dwa przyciski akcji. Ponadto, właściwość AutoCancel() w Powiadomieniu jest ustawiona na true.Kliknięcie Działania powiadamiania systemu Android nie zamyka szuflady powiadomień

Po kliknięciu przycisków akcji, system jest skonfigurowany do uruchamiania IntentService, która wywołuje NotificationManager.cancel(NOTIFICATION_ID), a następnie uruchamia działanie w nowym zadaniu.
Problem polega na tym, że chociaż to wywołanie usuwa powiadomienie z zasobnika, to nie zwija szuflady. Aktywność nazywana jest pobierana za szufladą.

Czy ktoś może rzucić nieco światła na to, jaki specjalny kod jest potrzebny do zamknięcia losowania oprócz anulowania powiadomienia?

Dziękuję.

+1

Czy kiedykolwiek znalazłeś rozwiązanie tego problemu? –

+6

Nie. Po prostu kilka hacków do użycia refleksji i rozwijania, zwiń pasek stanu. Wygląda na to, że jeśli intencja oczekująca zawiera zamiar, który rozwiązuje działanie, szuflada jest automatycznie zwinięta. Jeśli jednak oczekująca zamiar obejmuje usługę BroadcastReceiver lub usługę, tacka powiadomień zachowuje stan (rozwinięty). – Aster

Odpowiedz

0

System Android zwija szufladę powiadomień za każdym razem, gdy klikniesz powiadomienie i uruchomisz działanie lub transmisję. Nie sądzę, że istnieje jakiś programowy sposób zamknięcia szuflady powiadomień przez twój kod. Sugeruję, abyś sprawdził zamiary, które przekazałeś do konstruktora powiadomień i upewnił się, że podane są prawidłowe referencje. Myślę, że coś wewnątrz menedżera powiadomień na Androidzie jest blokowane z powodu zamierzonego przez ciebie zamiaru. Do tej pory nie widziałem, aby szuflada powiadomień pozostała otwarta po uruchomieniu akcji z powiadomienia. Po prostu ciekawy, czy twoja aktywność docelowa ma półprzezroczysty obszar, w którym poprzednia czynność jest widoczna, czy to jest to sugeruje, że sprawisz, że tło jest całkowicie nieprzezroczyste (bez przezroczystego/półprzezroczystego regionu). Może to uniemożliwić programowi startowemu Androidowi wykonanie sekwencji zatrzymania, a tym samym nie pozwolić programowi uruchamiającemu zamknąć szuflady powiadomień. Mam nadzieję, że mogłem ci pomóc. Wszystkiego najlepszego.

1

Chociaż ja bardzo doceniam, że odpowiedź Soumyajyoti powinny być poprawne ... to jest w rzeczywistości ...

używam

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

w układzie RemoteView na bieżąco powiadomienia ...

Mogę Cię zapewnić, że nie zamyka szuflady, ale strzela z zamiarem i wykonuje czynność za otwartą szufladą, a także wykonuje inne zadania, które przypisałem do odbiornika ...

Ja testowałem zarówno getActivity i getService (z których żadna nie będzie działać w moim okoliczności, muszę odpalić wiele zamiary onRecieve) i oboje zamknąć szufladę prawidłowo ...

wiem, że to nie jest odpowiedź, ale kiedy i jak ją znajdę, zgłoś się ponownie, aby edytować to ...

szalona myśl ... być może działanie bez widoku treści mogłoby być wywołane jako odbiornik, który wystrzeliłby odpowiednie intencje inne klasy lub aplikacje w razie potrzeby ...

Szalona myśl wymieniona powyżej działa ... Rozpocznij aktywność od PendingIntent. getActivity i użyj go, aby przekazać transmisje lub inne zamiary, a następnie zakończyć działanie ... efekt nie jest bezpośredni, ale niezauważalny dla użytkownika końcowego.

9

Znalazłem, że gdy używasz przycisków akcji w rozwiniętych powiadomieniach, musisz napisać dodatkowe kod i jesteś bardziej ograniczony.

Przed użyciem rozszerzonych powiadomień, domyślną akcją w moim powiadomieniu o pobraniu pliku było rozpoczęcie działania WIDO na pliku. Intencja VIEW została opakowana w intencję Chooser. Nie mogłem użyć oczekującej intencji dla zamiaru Chooser bezpośrednio z powiadomienia, ponieważ wybieracz wybiłby się, gdyby nie było żadnej aktywności, aby wyświetlić typ pliku. Miałem więc BroadcastReceiver, który uruchomiłby zamiar Chooser.

Po rozszerzeniu powiadomień zdecydowałem się zmienić powiadomienie o pobraniu pliku, więc domyślną akcją jest wyświetlenie działania szczegółów pliku przy użyciu przycisków czynności do wyświetlania i wysyłania. Jak zauważono przez użytkownika 2536953, uruchomienie odbiornika transmisji z powiadomienia nie zamyka szuflady powiadomień. Na podstawie jego informacji, że działanie zamknęło szufladę, zmieniłem odbiornik transmisji na powiadomienie bez żadnego interfejsu użytkownika.

Jak wskazano w tym poście How to dismiss Android notification after action has been clicked, innym problemem jest to, że musisz ręcznie anulować powiadomienie, gdy użytkownik kliknie przycisk akcji. Powiadomienie zostanie automatycznie anulowane tylko dla domyślnej akcji. Dodałem także kod w NotificationActivity, aby obsłużyć to.

budowaniu rozszerzony powiadomienia z widokiem i wysyłać przyciski:

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

budowaniu zamiar rozpocząć działalność od przycisków akcji zgłoszenia:

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

aktywność powiadomień bez 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); 
} 

Nie zapomnij dodać powiadomienia do AndroidManifest.xml.

+0

Dziękuję bardzo! –

+1

Byłem zobowiązany do ustawienia android: taskAffinity = "" w PowiadomienieActivity w przeciwnym razie był uruchomienie MainActivity również jeśli istniał w backstack –

+0

http://stackoverflow.com/questions/42527534/pending-action-expand-notification-on- kliknij Proszę mam pytanie –

36

Jeśli akcja jest w formie audycji lub usługi, ale zamierzają do szuflady powiadomienie, aby zwinąć, należy nadawać android.intent.action.CLOSE_SYSTEM_DIALOGS z onReceive. Spowoduje to ręczne zamknięcie szuflady.

+26

sendBroadcast (new Intent (Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); – goodhyun

+2

Metoda sendBroadcast znajduje się wewnątrz obiektu kontekstowego. –

+0

Dodałem te linie do mojego BroadcastReceiver przed wywołaniem context.startActivity (myIntent) Intent it = new Intent (Intent.ACTION_CLOSE_SYSTEM_DIALOGS); context.sendBroadcast (it); –

Powiązane problemy