56

Sto provando a utilizzare la nuova interfaccia delle notifiche. Ho aggiunto 3 pulsanti alle notifiche e voglio salvare qualcosa nel mio database una volta che ognuno di essi è stato cliccato.Determina clic su addAction per le notifiche Android

La notifica di per sé funziona bene e viene visualizzata quando chiamata, non so come catturare ciascuno dei tre diversi clic del pulsante.

Sto utilizzando uno BroadcastReceiver per catturare i clic, ma non so come dire quale pulsante è stato fatto clic.

Questo è il codice di AddAction (ho escluso il resto della notifica, come funziona bene) -

//Yes intent 
    Intent yesReceive = new Intent(); 
    yesReceive.setAction(CUSTOM_INTENT); 
    Bundle yesBundle = new Bundle();    
    yesBundle.putInt("userAnswer", 1);//This is the value I want to pass 
    yesReceive.putExtras(yesBundle); 
    PendingIntent pendingIntentYes = PendingIntent.getBroadcast(this, 12345, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
    mBuilder.addAction(R.drawable.calendar_v, "Yes", pendingIntentYes); 

    //Maybe intent 
    Intent maybeReceive = new Intent(); 
    maybeReceive.setAction(CUSTOM_INTENT); 
    Bundle maybeBundle = new Bundle();    
    maybeBundle.putInt("userAnswer", 3);//This is the value I want to pass 
    maybeReceive.putExtras(maybeBundle); 
    PendingIntent pendingIntentMaybe = PendingIntent.getBroadcast(this, 12345, maybeReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
    mBuilder.addAction(R.drawable.calendar_question, "Partly", pendingIntentMaybe); 

    //No intent 
    Intent noReceive = new Intent(); 
    noReceive.setAction(CUSTOM_INTENT); 
    Bundle noBundle = new Bundle();    
    noBundle.putInt("userAnswer", 2);//This is the value I want to pass 
    noReceive.putExtras(noBundle); 
    PendingIntent pendingIntentNo = PendingIntent.getBroadcast(this, 12345, noReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
    mBuilder.addAction(R.drawable.calendar_x, "No", pendingIntentNo); 

Questo è il codice della BroadcastReceiver -

public class AlarmReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.v("shuffTest","I Arrived!!!!"); 
    //Toast.makeText(context, "Alarm worked!!", Toast.LENGTH_LONG).show(); 

    Bundle answerBundle = intent.getExtras(); 
    int userAnswer = answerBundle.getInt("userAnswer"); 
    if(userAnswer == 1) 
    { 
     Log.v("shuffTest","Pressed YES"); 
    } 
    else if(userAnswer == 2) 
    { 
     Log.v("shuffTest","Pressed NO"); 
    } 
    else if(userAnswer == 3) 
    { 
     Log.v("shuffTest","Pressed MAYBE"); 
    } 

}   
} 

I registrato il BroadcastReceiver nel Manifesto. Inoltre, voglio menzionare che il BroadcastReceiver viene chiamato quando faccio clic su uno dei pulsanti nella notifica, ma l'intento include sempre un extra di "2".

Questa è la notifica iteslf - notification

+0

che è strano. Non vedo alcun errore nel tuo codice. Se cambi l'ordine di addAction() (e la creazione PendingIntent), ottieni ancora "2"? – Quanturium

+0

In questo caso mi dà solo l'ultima addAction() che ho chiamato – Tofira

+0

Posso registrare tre BroadcastReceiver per ciascuno dei tre pulsanti, ma voglio davvero evitarlo. – Tofira

risposta

103

È perché si sta utilizzando FLAG_UPDATE_CURRENT con intenti che hanno la stessa azione

Dalla documentazione:

se il PendingIntent descritto esiste già , quindi tienilo ma sostituisce i suoi dati extra con ciò che è in questo nuovo Intento.

Quando si specifica pendingIntentMaybe e pendingIntentNo, il sistema utilizza il PendingIntent creata per pendingIntentYes, ma sovrascrive gli extra. Pertanto, tutte e tre le variabili si riferiscono allo stesso oggetto e gli ultimi extra specificati erano per pendingIntentNo.

È necessario specificare un'azione alternativa per ogni Intent. Puoi ancora avere uno BroadcastReceiver, e devi solo intercettare tutte e tre le azioni.Questo sarebbe meno confusione semanticamente così :)

il poster di notifica:

//Yes intent 
Intent yesReceive = new Intent(); 
yesReceive.setAction(YES_ACTION); 
PendingIntent pendingIntentYes = PendingIntent.getBroadcast(this, 12345, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
mBuilder.addAction(R.drawable.calendar_v, "Yes", pendingIntentYes); 

//Maybe intent 
Intent maybeReceive = new Intent(); 
maybeReceive.setAction(MAYBE_ACTION); 
PendingIntent pendingIntentMaybe = PendingIntent.getBroadcast(this, 12345, maybeReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
mBuilder.addAction(R.drawable.calendar_question, "Partly", pendingIntentMaybe); 

//No intent 
Intent noReceive = new Intent(); 
noReceive.setAction(NO_ACTION); 
PendingIntent pendingIntentNo = PendingIntent.getBroadcast(this, 12345, noReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
mBuilder.addAction(R.drawable.calendar_x, "No", pendingIntentNo); 

Il ricevitore:

@Override 
public void onReceive(Context context, Intent intent) { 
    String action = intent.getAction(); 

    if(YES_ACTION.equals(action)) { 
     Log.v("shuffTest","Pressed YES"); 
    } else if(MAYBE_ACTION.equals(action)) { 
     Log.v("shuffTest","Pressed NO"); 
    } else if(NO_ACTION.equals(action)) { 
     Log.v("shuffTest","Pressed MAYBE"); 
    } 
}   
+1

Ho un dubbio che ho bisogno di cancellare. Sto usando una semplice classe di servizio per avviare, mettere in pausa e interrompere il servizio. C'è un pulsante immagine che cambierà la sua immagine disegnabile se faccio clic su Riproduci per mettere in pausa l'immagine o viceversa. Nel codice precedente hai menzionato mBuilder.addAction che contiene un drawable. Non riesco a capirlo dov'è l'id dell'immagine? è possibile avere due drawable ma solo per un pulsante immagine. –

+2

Ricevo un errore in YES_ACTION.equals (azione) perché? come risolvere questo problema. –

+0

dove e come impostare YES_ACTION, NO_ACTION ... ecc ... E quale aspetto avrà il file di manifist – Cripto

10

nel mio caso ha funzionato per me dopo aver aggiunto l'intento filtro

<receiver android:name=".AlarmReceiver"> 
     <intent-filter> 
      <action android:name="YES_ACTION"/> 
      <action android:name="NO_ACTION"/> 
      <action android:name="MAYBE_ACTION"/> 
     </intent-filter> 
    </receiver> 
+1

best practice (y) –

2

qui YES_ACTION deve essere yourfullpackagename.YES

come

private static final String YES_ACTION = "com.example.packagename.YES"; 

Allo stesso modo è possibile utilizzare NO_ACTION o MAYBE_ACTION

In BroadcastReceiver si deve utilizzare lo stesso YES_ACTION come dichiarato in precedenza,

significa in classe BroadcastReceiver è possibile verificare la presenza di personalizzato Trasmesso da seguente

public class NotificationReceiver extends BroadcastReceiver { 

private static final String YES_ACTION = "com.example.packagename.YES"; 
@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 
    String action = intent.getAction(); 
    if(YES_ACTION.equals(action)) { 
     Toast.makeText(context, "CALLED", Toast.LENGTH_SHORT).show(); 
    } 
} 

}

nota: invece di SÌ nella stringa YES_ACTION è possibile utilizzare anche un'altra parola.

8

STEP_BY_STEP

Fase 1

public void noto2() // paste in activity 
{ 
    Notification.Builder notif; 
    NotificationManager nm; 
    notif = new Notification.Builder(getApplicationContext()); 
    notif.setSmallIcon(R.drawable.back_dialog); 
    notif.setContentTitle(""); 
    Uri path = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
    notif.setSound(path); 
    nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 

    Intent yesReceive = new Intent(); 
    yesReceive.setAction(AppConstant.YES_ACTION); 
    PendingIntent pendingIntentYes = PendingIntent.getBroadcast(this, 12345, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT); 
    notif.addAction(R.drawable.back_dialog, "Yes", pendingIntentYes); 


    Intent yesReceive2 = new Intent(); 
    yesReceive2.setAction(AppConstant.STOP_ACTION); 
    PendingIntent pendingIntentYes2 = PendingIntent.getBroadcast(this, 12345, yesReceive2, PendingIntent.FLAG_UPDATE_CURRENT); 
    notif.addAction(R.drawable.back_dialog, "No", pendingIntentYes2); 



    nm.notify(10, notif.getNotification()); 
} 

Passo 1,5

ho creato una classe globale AppConstant

public class AppConstant 
    { 
    public static final String YES_ACTION = "YES_ACTION"; 
    public static final String STOP_ACTION = "STOP_ACTION"; 
    } 

Fase 2:

public class NotificationReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 
    String action = intent.getAction(); 
    if (AppConstant.YES_ACTION.equals(action)) { 
     Toast.makeText(context, "YES CALLED", Toast.LENGTH_SHORT).show(); 
    } 
    else if (AppConstant.STOP_ACTION.equals(action)) { 
     Toast.makeText(context, "STOP CALLED", Toast.LENGTH_SHORT).show(); 
    } 
} 

}

Fase 3

<receiver android:name=".NotificationReceiver"> 
     <intent-filter> 
      <action android:name="YES_ACTION"/> 
      <action android:name="STOP_ACTION"/> 

     </intent-filter> 
    </receiver> 
+0

funziona? hai provato questo? –

+0

Sì, funziona piuttosto bene, l'ho provato solo ora – ysfcyln

+0

Sto lavorando bene, ho provato, nessun problema ... – Venkat