56

Próbuję użyć nowego interfejsu powiadomień. Dodałem 3 przyciski do powiadomień i chcę zapisać coś do mojej bazy danych po kliknięciu każdego z nich.Określanie kliknięcia AddAction dla powiadomień systemu Android

Samo powiadomienie działa dobrze i jest wyświetlane po wywołaniu, po prostu nie wiem, jak uchwycić każde z trzech różnych kliknięć przycisku.

Używam BroadcastReceiver do przechwytywania kliknięć, ale nie wiem, jak stwierdzić, który przycisk został kliknięty.

Jest to kod z AddAction (mam wyłączone resztę powiadomienia, jak również jego pracy) -

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

Jest to kod 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 zarejestrowałem BroadcastReceiver w Manifeście. Ponadto chciałbym wspomnieć, że BroadcastReceiver jest wywoływana, gdy klikam jeden z przycisków w powiadomieniu, ale intencja zawsze zawiera dodatkowe "2".

To notifcation iteslf - notification

+0

to dziwne. Nie widzę żadnego błędu w Twoim kodzie. Jeśli zmienisz kolejność addAction() (i tworzenie PendingIntent), czy nadal otrzymujesz "2"? – Quanturium

+0

W tym przypadku po prostu daje mi ostatnią addAction() I zadzwonił – Tofira

+0

Mogę zarejestrować trzy BroadcastReceivers dla każdego z trzech przycisków, ale naprawdę chcę tego uniknąć. – Tofira

Odpowiedz

103

To dlatego, że używasz FLAG_UPDATE_CURRENT z zamiarów, które mają takie samo działanie

Od docs:

jeśli opisane PendingIntent już istnieje , a następnie zachowaj go, ale zastąp jego dodatkowe dane tym, co jest w tym nowym zamierzeniu.

Po określeniu pendingIntentMaybe i pendingIntentNo, system wykorzystuje PendingIntent stworzony dla pendingIntentYes, ale nadpisuje dodatki. Zatem wszystkie trzy zmienne odnoszą się do tego samego obiektu, a ostatnie dodatki zostały podane dla pendingIntentNo.

Należy podać alternatywne działanie dla każdego Intent. Nadal możesz mieć jeden BroadcastReceiver i po prostu przechwycić wszystkie trzy akcje.Byłoby to mniej mylące semantycznie jak dobrze :)

plakatu Powiadomienie:

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

Odbiornik:

@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

Mam wątpliwości, które muszę wyjaśnić. Używam prostej klasy usług do uruchamiania, wstrzymywania i zatrzymywania usługi. Tak więc istnieje jeden przycisk obrazu, który zmieni rysowany obraz, jeśli kliknę, tj. Odtwarzanie, aby wstrzymać obraz lub werset-werset. W powyższym kodzie wspomniałeś mBuilder.addAction, która zawiera losowanie. Nie jestem w stanie odgadnąć, gdzie jest id obrazu? czy możliwe jest posiadanie dwóch losowań, ale tylko dla jednego przycisku obrazu. –

+2

Otrzymuję błąd w YES_ACTION.equals (akcja), dlaczego? jak rozwiązać ten problem. –

+0

gdzie i jak ustawić YES_ACTION, NO_ACTION ... itd ... A jak będzie wyglądać plik manifestatora? – Cripto

10

w moim przypadku to zadziałało na mnie po dodaniu zamiarem filtr

<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

najlepsza praktyka (y) –

2

tutaj YES_ACTION musi być yourfullpackagename.YES

jak

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

Podobnie można użyć NO_ACTION lub MAYBE_ACTION

W BroadcastReceiver trzeba użyć tego samego YES_ACTION deklarowanego powyżej

oznacza w klasie BroadcastReceiver można sprawdzić za zwyczaj nadawane przez po

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

}

uwaga: zamiast TAK w łańcuchu YES_ACTION można również użyć innego wyrazu.

8

STEP_BY_STEP

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

Krok 1,5

I stworzył globalną klasę AppConstant

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

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

}

Etap 3

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

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

czy to działa? czy to przetestowałeś? –

+0

Tak, działa całkiem nieźle, przetestowałem to właśnie teraz – ysfcyln

+0

Dobrze działa, próbowałem bez problemów ... – Venkat