I'm noticing the tracking pending intents that I send out via the standard SmsManager in Android doesn't seem to retain the extra information in them. Example:
Intent sentIntent = new Intent(SENT);
sentIntent.putExtra("value1", "foo"); // <- note this value
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(numberToSendTo, null, mMessageToSend, sentPI, null);
//... in the broadcastReceiver that catches the SENT intent ...
public void onReceive(Context arg0, Intent arg1) {
arg1.getExtras().getString("value1"); // <- nothing, no such key
}
Can someone test this out, was this behaviour intended and I am doing it wrong, or is this a bug to be filed for Android?
Try adding the flag FILL_IN_SELECTOR when you create the PendingIntent (see the spec for PendingIntent.getBroadcast for the flags and their general behavior). This should force the PendingIntent to take in all the top-level extras from the Intent.
Related
In the messaging program I made, I used pending intent to receive the message sending and delivery report. When I send several messages and wait for the delivery report, the program does not recognize which message the received pending intent belongs to.
My code is:
sentSMS = PendingIntent.getBroadcast(this, msgId(), new Intent(SMS_SENT), 0); deliverSMS = PendingIntent.getBroadcast(this, msgId(), new Intent(SMS_DELIVERED), 0);
According to what I searched for, I have to use the request code parameter for this, for each message I have assigned a request code **(the ID of each message from the database) **in pending intent, but I don't know how to receive it in on receive.
thanks
Also i tried this:
Intent deliveryIntent = new Intent();
deliveryIntent.putExtra("id", msgId());
deliverSMS = PendingIntent.getBroadcast(this, msgId(), deliveryIntent, 0);
//************
Intent sendIntent = new Intent();
sendIntent.putExtra("id", msgId ());
sentSMS = PendingIntent.getBroadcast(this, msgId(), sendIntent, 0);
But I did not receive anything in extra
TThanks 🙏
When you create the PendingIntent, you need to specify PendingIntent.UPDATE_CURRENT as the last parameter of the getBroadcast() call. This will ensure that each PendingIntent has the correct "id".
In onReceive() you should get the broadcast Intent and it should contain the "extra" named "id" with the message ID.
However, if you create the Intent without an ACTION and without a component or package name, your onReceive() will never get called. Please edit your question and show how you have set up your BroadcastReceiver.
Does anyone know if there are any changes to how Android 7.0 (Nougat) handles intent extras compared to Android 6.0 (Lollipop)?
Long story short: my app works as intended on all versions from 4.1(16) to 6.0(23) but crashes on android 7.0(24)!
The app creates a pending intent with an intent to a custom broadcast receiver which has extras. However, on android 7 none of the extras are present in the intent received by the broadcast receiver.
MainActivity.java
Intent intent = new Intent(context, PollServerReceiver.class);
// TODO: Remove after DEBUGGING is completed!
intent.putExtra("TESTING1", "testing1");
intent.putExtra("TESTING2", "testing2");
intent.putExtra("TESTING3", "testing3");
// PendingIntent to be triggered when the alarm goes off.
final PendingIntent pIntent = PendingIntent.getBroadcast(context,
PollServerReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup alarm to schedule our service runs.
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstRun, freqMilis, pIntent);
PollServerReceiver.java
Bundle extras = intent.getExtras();
Log.d(TAG, "onReceive: TESTING1 = " + extras.getString("TESTING1")); // null here
// None of the three "TESTING*" keys are there!
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(TAG, String.format("onReceive extra keys: %s %s (%s)", key, value.toString(), value.getClass().getName()));
}
Stack trace obviously gives the NullPointerException as the cause of crash.
It would not be so weird if it would crash among all versions, but in this case its the latest android only. Has anyone got any ideas please?
Note: I have tried creating pending intents with different flags including (0, PendingIntent.FLAG_UPDATE_CURRENT, PendingIntent.FLAG_CANCEL_CURRENT) still got the exact same result.
Putting a custom Parcelable in a PendingIntent has never been especially reliable, and it flat-out will not work in an AlarmManager PendingIntent on Android 7.0. Other processes may need to fill in values into the Intent, and that involves manipulating the extras, and that can't be done in any process but your own, since no other process has your custom Parcelable class.
This SO answer has a workaround, in the form of converting the Parcelable yourself to/from a byte[].
I had a similar problem but I think I found an easy solution. Put your data inside a Bundle and send that Bundle with your intent. In my case I wanted to send a serializable object with my intent.
Setup the alarm:
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReciever.class);
Bundle bundle = new Bundle();
//creating an example object
ExampleClass exampleObject = new ExampleClass();
//put the object inside the Bundle
bundle.putSerializable("example", exampleObject);
//put the Bundle inside the intent
intent.putExtra("bundle",bundle);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//setup the alarm
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
Receive the alarm:
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// get the Bundle
Bundle bundle = intent.getBundleExtra("bundle");
// get the object
ExampleClass exampleObject = (ExampleClass)bundle.getSerializable("example");
}
}
It worked fine for me. Hope it helps :)
I'm trying to send SMS messages from an Android App. I'm using PendingIntent to so I can use a Broadcast Receiver to check if it was sent ok. As the sendTextMessage call will be done per SMS, I need to send some "extra" data to identify the actual SMS, so as my broadcast receive can do some work on a specific SMS Message.
Here is my sending code:
String SENT = "SMS_SENT";
Intent sentIntent = new Intent(SENT);
sentIntent.putExtra("foo", "BAR");
PendingIntent sentPI = PendingIntent.getBroadcast(baseContext, 0,
sentIntent, 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(baseContext, 0,
new Intent(DELIVERED), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(smsMessage.getNumber(), null, smsMessage.getText(), sentPI, deliveredPI);
The problem is that in my BroadCast receiver, it can't seem to read my Extra "foo":
public class SMSSentBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent intent) {
String smsID = intent.getStringExtra("foo");
......
}
}
smsID just becomes null.
My broadcast receiver is registered like so:
baseContext.registerReceiver(new SMSSentBroadcastReceiver(), new IntentFilter("SMS_SENT"));
Given that the intent filter is working, what am I doing wrong? Why aren't the extras sent as well?
Any help is appreciated. Thanks
What I suspect has happened (at least, it's happened to me), is that you're using the SMS_SENT intent somewhere else prior, whereby at that time, that intent doesn't have "foo" in the extras. Calling PendingIntent.getBroadcast with the same intent and request code will return you the original pending intent.
If it's actually meant to be the same intent, you need to use something like a PendingIntent.FLAG_UPDATE_CURRENT to update the intent with the new extras. If it's not suppose to be the same intent, it should have a different request code, so that it doesn't match the other intent (which is why feeding in a unique request code worked).
I got a custom status bar notification. There is a "Play" and "Next" image on it.
I want to send a Broadcast Intent to a Service when the "play" or "next" image is pressed.
notification = new Notification(R.drawable.ic_launcher, title + "\n"
+ text, System.currentTimeMillis());
contentIntent = PendingIntent.getActivity(context, 0, actionOnClick, 0);
notification.contentIntent = contentIntent;
contentView = new RemoteViews(context.getPackageName(),
R.layout.custom_player_notification);
contentView.setTextViewText(R.id.custom_player_notification_title,
title);
contentView.setTextViewText(R.id.custom_player_notification_text, text);
notification.contentView = contentView;
This is the code.
The ContentView offers the possibility to set "setOnClickPendingIntent" and "setOnClickFillInIntent". How can I use them to send this broadcast?
I want to send a broadcast because I dont want to launch an activity.
I want to send a Broadcast Intent to a Service when the "play" or "next" image is pressed
I would suggest that you want to send a command via startService() rather than a broadcast.
How can I use them to send this broadcast?
You can try calling setOnClickPendingIntent(), supplying a PendingIntent you create via the static getBroadcast() method on PendingIntent (for a broadcast) or getService() (for a command to be sent via startService()).
Bear in mind that none of this will work on most Android devices available at present. I think buttons-in-Notifications works starting on Android 4.0, perhaps 3.0, but definitely not before then.
You could put something similar to this in your onClick() method of the notification, directing it to a broadcast receiver.
Intent intent = new Intent(this, receiver.class);
intent.putExtra("SomeInfoMaybe", info);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_CANCEL_CURRENT);
And then the code for handling the next stage could go in here:
public class receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
System.out.println("SomeInfoMaybe = " + bundle.getString("info"));
//etc...
}
}
calling .notify(); on your notification should help link to the broadcast receiver
i'm using the code
private void sendSms(String phoneNo, String message){
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this, MainScreen.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNo, null, message, pi, null);
}
i have utilized the onSaveInstanceState to save values such as text and spinner position, which will keep things saved and consistent while receiving intents, navigating away from the activity, etc
not sure if i can put extras in the pending intent, so that when it starts my main activity, i can use those extras. because somehow, when the pending intent goes through, i need it to restore to the way it was before the intent was called
You can.. but you must clear the previous pending intent or use the one shot flag while constructing your pending intent.. like this
Intent sentIntent = new Intent(SENT_SMS_ACTION);
sentIntent.putExtra(MESSAGE_ID_TAG, messageId);
PendingIntent sentPendingIntent = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_ONE_SHOT);