PendingIntent no envía Intent extras

127

Mi MainActicity comienza RefreshServicecon un Intentque tiene un booleanextra llamadoisNextWeek .

Mi RefreshServicehace un Notificationque inicia mi MainActivitycuando el usuario hace clic en él.

esto se ve así:

    Log.d("Refresh", "RefreshService got: isNextWeek: " + String.valueOf(isNextWeek));

    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);

    Log.d("Refresh", "RefreshService put in Intent: isNextWeek: " + String.valueOf(notificationIntent.getBooleanExtra(MainActivity.IS_NEXT_WEEK,false)));
    pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

    builder = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText("ContentText").setSmallIcon(R.drawable.ic_notification).setContentIntent(pendingIntent);
    notification = builder.build();
    // Hide the notification after its selected
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notificationManager.notify(NOTIFICATION_REFRESH, notification);

Como puede ver, notificationIntentdebe tener el booleanextra IS_NEXT_WEEKcon el valor del isNextWeekcual se coloca en el PendingIntent.

Cuando hago clic en esto Notification, siempre obtengo el falsevalor deisNextWeek

Esta es la forma en que obtengo el valor en MainActivity:

    isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);

Iniciar sesión:

08-04 00:19:32.500  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity sent: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService got: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService put in Intent: isNextWeek: true
08-04 00:19:41.990  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity.onCreate got: isNextWeek: false

Cuando empiezo directamente MainActivitycon un Intentcon el "Valor siguiente" de esta manera:

    Intent i = new Intent(this, MainActivity.class);
    i.putExtra(IS_NEXT_WEEK, isNextWeek);
    finish();
    startActivity(i);

todo funciona bien y me sale truecuando isNextWeekestá true.

¿Qué hago mal que siempre hay un falsevalor?

ACTUALIZAR

Esto resuelve el problema: https://stackoverflow.com/a/18049676/2180161

Citar:

Mi sospecha es que, dado que lo único que cambia en la intención son los extras, el PendingIntent.getActivity(...)método de fábrica es simplemente reutilizar la intención anterior como una optimización.

En RefreshService, intente:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

Ver:

http://developer.android.com/reference/android/app/PendingIntent.html#FLAG_CANCEL_CURRENT

ACTUALIZACIÓN 2

Vea la respuesta a continuación por qué es mejor usarlo PendingIntent.FLAG_UPDATE_CURRENT.

maysi
fuente
2
PendingIntent.FLAG_CANCEL_CURRENT funcionó para mí, gracias
Pelanes
1
Me ahorró muchas horas de trabajo. ¡respuesta correcta!
TharakaNirmana
tienes la pregunta y la solución: D genial. Creo que deberías agregarlo como respuesta a las preguntas. + 10s es mejor que + 5s;)
Muhammed Refaat
Con referencia a esta solución: stackoverflow.com/questions/1198558/…
M.Noman
El FLAG_UPDATE_CURRENT no fue suficiente en mi caso, ya que mi widget reutilizó el mismo PendingIntent. Terminé usando FLAG_ONE_SHOT para la acción que ocurre raramente, y dejé el widget PendingIntent intacto.
Eir

Respuestas:

29

Usar PendingIntent.FLAG_CANCEL_CURRENT no es una buena solución debido al uso ineficiente de la memoria. En su lugar, use PendingIntent.FLAG_UPDATE_CURRENT .

Utilice también Intent.FLAG_ACTIVITY_SINGLE_TOP (la actividad no se iniciará si ya se está ejecutando en la parte superior de la pila del historial).

Intent resultIntent = new Intent(this, FragmentPagerSupportActivity.class).
                    addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);  
resultIntent.putExtra(FragmentPagerSupportActivity.PAGE_NUMBER_KEY, pageNumber);

PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        resultIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );

Luego:

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

            int startPageNumber;
            if ( savedInstanceState != null)
            {
                startPageNumber = savedInstanceState.getInt(PAGE_NUMBER_KEY);
//so on

Debería funcionar ahora.


Si aún no ha esperado el comportamiento, intente implementar el void onNewIntent(Intent intent)controlador de eventos, de esa manera puede acceder a la nueva intención que se llamó para la actividad (que no es lo mismo que simplemente llamar a getIntent (), esto siempre devolverá la primera intención que se lanzó tu actividad

@Override
protected void onNewIntent(Intent intent) {
    int startPageNumber;

    if (intent != null) {
        startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
    } else {
        startPageNumber = 0;
    }
}
Yuliia Ashomok
fuente
21

Creo que necesita actualizar el Intentcuando recibe uno nuevo anulando onNewIntent(Intent)en su Actividad. Agregue lo siguiente a su actividad:

@Override
public void onNewIntent(Intent newIntent) {
    this.setIntent(newIntent);

    // Now getIntent() returns the updated Intent
    isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);        
}

Editar:

Esto es necesario solo si su Actividad ya se inició cuando se recibe la intención. Si su actividad se inicia (y no solo se reanuda) por la intención, entonces el problema está en otra parte y mi sugerencia puede no solucionarlo.

Vikram
fuente
esto aparece también si la actividad se cierra y luego se abre con la notificación.
maysi
3

El siguiente código debería funcionar: -

int icon = R.drawable.icon;
String message = "hello";
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);

Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("isNexWeek", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);

En MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
        boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
Haris ur Rehman
fuente
new Notification(icon, message, when);está en desuso
maysi
¿De todos modos hacerlo sin CLEAR_TOP?
Richard