Notification created by IntentService uses always a wrong Intent

maysi picture maysi · Aug 5, 2013 · Viewed 13.4k times · Source

Problem

When the user presses Send "Button 1"(scroll down to see the construction of the app) a new Notification is created from the RefreshService. If the user presses this notification a MainActivity instance gets started and receives a String with the value Button 1 over the Intent.

This value gets displayed.

When the user presses now the Send "Button 2" a new Notification is created from the RefreshService. If the user presses this notification a MainActivity instance gets started and receives a String ALSO with the value Button 1 over the Intent.

So as you can guess, normally there should be the value Button 2.

When the first Button the user pressed was Send "Button 2" then there would allways Button 2 be sent.

The only sollution to get the value of the second button is to restart the phone and pressing the second button first. Even force close doesn't work.

I know that I also can change the UI in another way. But I need this approach in a app where I need to restart the 'MainActivity' with another Intent so the approach should be the same.

Construction

MainActivity

public class MainActivity extends Activity implements View.OnClickListener {
    public static final String RECEIVED = "received";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((TextView)findViewById(R.id.textView_received)).setText(getIntent().getStringExtra(RECEIVED));

        findViewById(R.id.button_1).setOnClickListener(this);
        findViewById(R.id.button_2).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, RefreshService.class);

        if(v.getId() == R.id.button_1){
            intent.putExtra(RECEIVED, "Button 1");
            Toast.makeText(this,"Sent \"Button 1\"",Toast.LENGTH_LONG).show();
        }
        else if(v.getId() == R.id.button_2){
            intent.putExtra(RECEIVED, "Button 2");
            Toast.makeText(this,"Sent \"Button 2\"",Toast.LENGTH_LONG).show();
        }

        startService(intent);
    }
}

RefreshService

public class RefreshService extends IntentService {
    public RefreshService() {
        super("RefreshService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String received = intent.getStringExtra(MainActivity.RECEIVED);

        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.putExtra(MainActivity.RECEIVED, received);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

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

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setContentTitle("IntentServiceRefresh").setContentText(received).setSmallIcon(R.drawable.ic_notification_small).setContentIntent(pendingIntent);
        Notification notification = builder.build();

        // Hide the notification after it's selected
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notification);
    }
}

App Layout
App Layout

Answer

sddamico picture sddamico · Aug 5, 2013

My suspicion is that, since the only thing changing in the Intent is the extras, the PendingIntent.getActivity(...) factory method is simply re-using the old intent as an optimization.

In RefreshService, try:

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

See:

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