PendingIntent não envia extras de intenção

127

Meu MainActicity começo RefreshServicecom um Intentque tem um booleanextra chamadoisNextWeek .

Meu RefreshServicefaz um Notificationque inicia meu MainActivityquando o usuário clica nele.

isso é assim:

    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 você pode ver, notificationIntentdeve ter o booleanextra IS_NEXT_WEEKcom o valor isNextWeekcolocado no PendingIntent.

Quando clico agora Notification, sempre obtenho falseo valor deisNextWeek

É assim que obtenho o valor no MainActivity:

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

Registro:

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

Quando eu inicio diretamente o MainActivitycom um Intentcom o "Próximo Valor", desta forma:

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

tudo funciona bem e eu entendo truequando isNextWeeké true.

O que eu faço de errado que sempre exista um falsevalor?

ATUALIZAR

isso resolve o problema: https://stackoverflow.com/a/18049676/2180161

Citar:

Minha suspeita é que, como a única coisa que muda no Intent são os extras, o PendingIntent.getActivity(...)método de fábrica é simplesmente reutilizar o antigo intento como uma otimização.

Em RefreshService, tente:

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

Vejo:

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

ATUALIZAÇÃO 2

Veja a resposta abaixo por que é melhor usar PendingIntent.FLAG_UPDATE_CURRENT.

maysi
fonte
2
PendingIntent.FLAG_CANCEL_CURRENT trabalhou para mim, graças
Pelanes
1
me salvou muitas horas de trabalho. resposta correta!
TharakaNirmana
você tem a pergunta e a solução: D ótimo. Eu acho que você deve adicioná-lo como uma resposta para a pergunta. + 10s é melhor que + 5s;)
Muhammed Refaat
Referenciando a esta solução: stackoverflow.com/questions/1198558/…
M.Noman
O FLAG_UPDATE_CURRENT não foi suficiente no meu caso, pois o mesmo PendingIntent foi reutilizado pelo meu widget. Acabei usando FLAG_ONE_SHOT para a ação que ocorre raramente e deixei o widget PendingIntent intacto.
Eir

Respostas:

29

Usar PendingIntent.FLAG_CANCEL_CURRENT não é uma boa solução devido ao uso ineficiente de memória. Em vez disso, use PendingIntent.FLAG_UPDATE_CURRENT .

Use também Intent.FLAG_ACTIVITY_SINGLE_TOP (a atividade não será iniciada se já estiver em execução na parte superior da pilha do histórico).

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

Então:

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

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

Deve funcionar agora.


Se você ainda não esperava um comportamento, tente implementar o void onNewIntent(Intent intent)manipulador de eventos, para acessar a nova intenção que foi chamada para a atividade (que não é a mesma que chamar getIntent (), isso sempre retornará o primeiro Intent lançado sua atividade.

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

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

Eu acho que você precisa atualizar Intentquando receber uma nova substituindo onNewIntent(Intent)em sua Atividade. Adicione o seguinte à sua atividade:

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

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

Editar:

Isso é necessário apenas se sua Atividade já tiver sido iniciada quando a intenção for recebida. Se sua atividade é iniciada (e não apenas retomada) pela intenção, o problema está em outro lugar e minha sugestão pode não ser corrigida.

Vikram
fonte
isso também aparece se a atividade for fechada e depois aberta com a notificação.
Maysi
3

O código a seguir deve 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);

Em MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
        boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}
Haris ur Rehman
fonte
new Notification(icon, message, when);está obsoleto
maysi
Enfim, fazer isso sem CLEAR_TOP?
Richard