16

Sto tentando di aggiungere un elemento di azione di notifica nella mia app che è un lettore musicale. Quando viene avviato uno stream, deve essere attivata una notifica e nella notifica deve essere visualizzato un pulsante di arresto per lo streaming. La notifica funziona bene finora, ho problemi con l'elemento di azione di arresto. Ecco come viene dichiarato nel servizio di avviare il flusso:.Notifica Android Azione non attivata (PendingIntent)

Intent stopIntent = new Intent(this, MusicPlayerNew.class); 
stopIntent.putExtra("STOP", "STOP"); 
PendingIntent stopPendingIntent = PendingIntent.getActivity(this, 0, 
       stopIntent, PendingIntent.FLAG_UPDATE_CURRENT, null); 
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent); 

Ora, nel onResume() - Metodo della mia attività verifico con getIntent() getStringExtra() per la "STOP" in più, ma la intento ho recuperato tramite getIntent() non ha nessun extra impostati :(

ho anche cercato di controllo per inviare una trasmissione (ho un ricevitore di broadcast di lavoro di comunicare da servizio per l'attività)

Intent stopIntent2 = new Intent(MusicPlayerNew.STOP_MEDIAPLAYER); 
PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0, 
       stopIntent2, PendingIntent.FLAG_UPDATE_CURRENT); 
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent2); 

Ora questo funziona se l'attività è attualmente in primo piano Se l'attività è i n fondo il pulsante di arresto non fa nulla :(

EDIT: Ho il BroadcastReceiver nella mia attività di classe privata

private class DataUpdateReceiver extends BroadcastReceiver { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
.. 
}} 

Nel onResume() registrare il mio app per questo ricevitore:

intentFilter = new IntentFilter(STOP_MEDIAPLAYER); 
registerReceiver(dataUpdateReceiver, intentFilter); 

onPause()

unregisterReceiver(dataUpdateReceiver); 

Ora se rimuovo l'annullamento della registrazione dal metodo onPause() - la trasmissione viene ricevuta anche se l'app/attività non è più in primo piano. Ma è questo il modo giusto per farlo? Ho ottenuto questo registro/unregister-stuff da un tutorial sul Web.

+0

Ho lo stesso problema su KitKat. Ho due azioni, prima chiamata bella, seconda non chiamata affatto. Hai trovato il modo di risolvere questo problema? – Nik

+0

Ok, ho trovato una soluzione. Guarda la mia risposta in basso. – Nik

risposta

9

trovo soluzione in questa discussione su Google Code https://code.google.com/p/android/issues/detail?id=61850

per risolvere il problema è necessario aggiungere PendingIntent.FLAG_CANCEL_CURRENT bandiera per il vostro PendingIntent.

PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0, 
      stopIntent2, PendingIntent.FLAG_CANCEL_CURRENT); 
+0

Grazie. Questo mi ha davvero fatto impazzire quando ho avuto un problema simile. Questo ha fatto il trucco. Potrebbe essere un riavvio del dispositivo avrebbe aiutato anche, ma questo è pulito. – sivag1

0

Non si riceve la trasmissione quando è in background perché si annulla la registrazione in onPause. Sposta il codice unregisterReceiver nella funzione onDestroy. Questo sarà chiamato solo quando l'attività è distrutta. Oppure puoi annullare la registrazione una volta verificato l'evento previsto.

2

Più che usare il ricevitore broadcast, è necessario utilizzare un servizio e dichiarare una nuova azione nel vostro servizio in questo modo:

public final String ACTION_STOP = "yourpackagename.ACTION_STOP"; 

e quindi creare i tuoi intenti in questo modo:

Intent stopIntent = new Intent(this, YourService.class).setAction(YourService.ACTION_STOP); 
PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, 0); 

Naturalmente , interrompere la riproduzione nella funzione del servizio startCommand, se l'azione del intent è uguale a ACTION_STOP.

Questo dovrebbe fare il trucco;)

0

Ci sono molteplici domande qui:

Parte 1: Perché è il vostro intento non riceve il "STOP" in più? Anche se non è visto nel codice che hai fornito, volevo confermare se stai utilizzando il flag FLAG_ACTIVITY_SINGLE_TOP per l'intento di notifica? Se è così, l'intento che riceverai nella tua attività sarebbe l'intento che ha iniziato l'attività e quindi l'extra "STOP" non sarà disponibile. È necessario estendere lo onNewIntent() in questo caso (dove viene inviato il nuovo intent). More info here.
Se non si è utilizzato FLAG_ACTIVITY_SINGLE_TOP, significa che viene creata una nuova attività quando viene toccata la notifica, nel qual caso l'Intent deve avere il parametro "STOP". Se riesci a fornirmi tutto il codice pertinente, posso aiutarti meglio.

Parte 2: Uso del ricevitore di trasmissione Questo non è semplice, come hai già scoperto. Dovresti annullare la registrazione in onDestroy e se la tua attività è chiusa dall'utente, onDestroy potrebbe essere chiamato e il tuo destinatario potrebbe non essere attivo nel momento in cui la notifica viene toccata dall'utente. Se non annulli la registrazione, potrebbe sembrare che funzioni, ma si tratta di una perdita di memoria, GC potrebbe ripulire in qualsiasi momento, il che potrebbe causare un arresto anomalo del tuo programma, ad esempio, DEVI annullare la registrazione. Se hai bisogno di andare con l'approccio del ricevitore broadcast, devi avere un servizio per farlo e il servizio ha le sue insidie ​​-> riavvio per sistema, esaurimento della batteria, ecc. Ti consiglio caldamente di seguire il tuo primo approccio.

5

mi sono imbattuto in questo problema oggi ed è stato causato dalla attività di non essere registrato o aggiunto alla AndroidManifest.xml. Pensavo di averlo lì dentro ma non lo era. Inoltre, nessun errore veniva registrato cercando di invocare l'azione con il suo intento.

Ho capito creando un intent e chiamando startAcitivty (intent) senza utilizzare una notifica. Quindi mi ha dato un errore affermando che probabilmente l'attività mancava dal manifest.

Se nessuna delle altre risposte risolve il problema, si spera che questo succeda. Solitamente i problemi difficili sono il risultato di qualcosa di semplice e sciocco.

6

Mi sono imbattuto in questo problema oggi. Nel mio caso utilizzava gli extra di intento memorizzati nella cache da un'istanza precedente dell'intento in quanto tutti i parametri per i costruttori pendingIntent erano gli stessi. Ho trovato due soluzioni per questo ...

  1. Utilizzo di FLAG_CANCEL_CURRENT come indicato da Nik.
  2. Passaggio di un unico requestCode al pendingIntent come segue

    PendingIntent pi = PendingIntent.getService(this, UNIQUE_ID, pi, 0); 
    

Nel mio caso, il secondo metodo risolto il problema come ho bisogno di mantenere in vita le notifiche precedenti. Potrebbe essere questo aiuterà una persona con problemi simili.

+0

Non credo che UNIQUE_ID sia necessario, a meno che non ci sia un conflitto con un altro servizio. –

0

Avevo un problema molto simile ma una soluzione molto diversa. Anche l'intenzione in sospeso non viene attivata se hai dichiarato <service android:enabled="false"></service> nel file manifest.xml.

Sostituire android:enabled="false"-android:enabled="true"

Questo potrebbe non essere un problema diretta del problema. Ma se crei il servizio in Android Studio utilizzando il modello predefinito, aggiunge automaticamente queste proprietà al servizio.

0

Per me, la soluzione era quella di impostare le bandiere del intento:

resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 
       Intent.FLAG_ACTIVITY_CLEAR_TASK); 
6

Questa è la risposta molto tardi ma può aiutare qualcuno:

Si consiglia di scegliere il giusto tipo di intenti In attesa di base sull'intento che vuoi correre. Ecco alcuni esempi:

Per Attività utilizzo qui di seguito:

Intent i = new Intent(this, YourActivity.class); 
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0); 

Per Servizio utilizzo qui di seguito:

Intent i = new Intent(this, YourService.class); 
PendingIntent pi = PendingIntent.getService(this, 0, i, 0); 

Per Broadcast Receiver utilizzo qui di seguito:

Intent i = new Intent(this, YourReciver.class); 
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); 

Potrebbe essere necessario modificare il codice di richiesta e le bandiere se necessario

Problemi correlati