getExtra from Intent launched from a pendingIntent

21,998

Solution 1

If you change the Extra's value in the intent, then while creating the pending intent you should use the flag PendingIntent.FLAG_CANCEL_CURRENT.

A simple example would be

PendingIntent pi = PendingIntent.getBroadcast(context, 0,intentWithNewExtras,PendingIntent.FLAG_CANCEL_CURRENT);

This is the right way and will ensure that your new values are delivered.

Hope it helps.

Solution 2

Intents are reused in the system, unless they differ on context/action I believe. Documentation Link. That is, if you have already constructed an Intent, that intent might be used later as well.

As a debug-test, you could try to add intent.setAction("" + Math.random()) below intent.putExtras(c) and see if your extras are received in the other end.

Relevant Documentation:

Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.

Solution 3

use different request code for different alarm notifications to avoid overwriting of same alarm time.

Share:
21,998
spagi
Author by

spagi

Updated on February 12, 2020

Comments

  • spagi
    spagi about 4 years

    I am trying to make some alarms after the user selects something with a time from a list and create a notification for it at the given time. My problem is that the "showname" that a putExtra on my Intent cant be received at the broadcast receiver. It always get null value. This is the way I do it for most of my intents but I think this time maybe because of the pendingIntent or the broadcastReceiver something need to be done differentelly. Thank you

    The function that sends the Intent through the pending intent

    public void setAlarm(String showname,String time) {
    
        String[] hourminute=time.split(":");
        String hour = hourminute[0];
        String minute = hourminute[1];
        Calendar rightNow = Calendar.getInstance();
        rightNow.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour));
        rightNow.set(Calendar.MINUTE, Integer.parseInt(minute));
        rightNow.set(Calendar.SECOND, 0);
        long t=rightNow.getTimeInMillis();
        long t1=System.currentTimeMillis();
    
        try {   
    
        Intent intent = new Intent(this, alarmreceiver.class);  
        Bundle c = new Bundle();            
        c.putString("showname", showname);//This is the value I want to pass
        intent.putExtras(c);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 12345, intent, 0);
    
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, rightNow.getTimeInMillis(),pendingIntent);
        //Log.e("ALARM", "time of millis: "+System.currentTimeMillis());
        Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
    
        } catch (Exception e) {
            Log.e("ALARM", "ERROR IN CODE:"+e.toString());
        }
    }
    

    And this is the receiving end

    public class alarmreceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        // Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();      
        Bundle b = intent.getExtras();
        String showname=b.getString("showname");//This is where I suppose to receive it but its null
        NotificationManager manger = (NotificationManager) context
                .getSystemService(context.NOTIFICATION_SERVICE);
    
        Notification notification = new Notification(R.drawable.icon,
                "TVGuide Υπενθύμιση", System.currentTimeMillis());
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                new Intent(context, tvguide.class), 0);
    
        notification.setLatestEventInfo(context, "Το Πρόγραμμα Ξεκίνησε",
                showname, contentIntent);
    
        notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;
    
        notification.sound = Uri.parse("file:///sdcard/dominating.mp3");
        notification.vibrate = new long[]{100, 250, 100, 500};
        manger.notify(1, notification);
    }           
    }
    
  • Andrey Novikov
    Andrey Novikov about 12 years
    This is the best answer for this kind of questions! Very simple and beautiful workaround for a problem.
  • Necronet
    Necronet over 11 years
    This does not seem to work in widget with flipper aparently once an intent is launched the system tries to reutilize it and no extra is changed.
  • Ali
    Ali over 11 years
    Worked for me, I was stuck for hours!
  • Snicolas
    Snicolas almost 11 years
    +1, this is the right answer, it should be accepted. It is really useful, Thx. (BTW, you can also use a different request code when creating pending intents, with a hash, that's quite convenient).
  • Chad Bingham
    Chad Bingham over 9 years
    Access the intend bundle just like usual?