intent.putExtra() in pending intent not working - android

I am passing a pending intent through alarmreceiver, from a service class. But, after the pendingIntent fires, the intent.putExtra() information is not being received by the broadcastreceiver class. Here is my code for firing the pendingIntent
Intent aint = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, aint, PendingIntent.FLAG_UPDATE_CURRENT);
aint.putExtra("msg", msg);
aint.putExtra("phone", phone);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
The alarm receiver class is below
public String msg, phonen;
#Override
public void onReceive(Context context, Intent intent){
Bundle extras = intent.getExtras();
msg = extras.getString("msg");
phonen = extras.getString("phone");
Log.d("onReceive", "About to execute MyTask");
Toast.makeText(context,msg, Toast.LENGTH_LONG).show();
}
The msg information in toast, that is being received from pending intent, is not being shown. Instead, a blank toast is shown.

Try this
Intent aint = new Intent(getApplicationContext(), AlarmReceiver.class);
aint.putExtra("msg", msg);
aint.putExtra("phone", phone);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(),
id,
aint,
// as stated in the comments, this flag is important!
PendingIntent.FLAG_UPDATE_CURRENT);

Remember to put an unique id in the PendingIntent constructor, or you could get some weird thing when you try to get the putExtra values.
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(),
UUID.randomUUID().hashCode(),
aint,
PendingIntent.FLAG_UPDATE_CURRENT
);

You have to use getStringExtra() and be sure the String are not null:
Intent intent = getIntent();
msg = intent.getStringExtra("msg");
phonen = intent.getStringExtra("phone");
if(msg!=null){
Toast.makeText(context,msg,
Toast.LENGTH_LONG).show();
}
and reverse Your putExtras before PendingIntent:
Intent aint = new Intent(getApplicationContext(), AlarmReceiver.class);
aint.putExtra("msg", msg);
aint.putExtra("phone", phone);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, aint, PendingIntent.FLAG_UPDATE_CURRENT);

This is because you are first initialize Intent and add to PendingIntent. After that you are adding info in intent. You should add info to intent then add this intent to PendingIntent.

In my case i was missing PendingIntent.FLAG_UPDATE_CURRENT as flag.

final Intent my_intent = new Intent(this.context , Alarm_Receiver.class);
//put in extra string into my intent
//tell the clock that the user pressed the "alarm on button"
my_intent.putExtra("extra" , 1);
int state = my_intent.getExtras().getInt("extra");
Log.i("extraa" , "the state in the main activity in alarm on Button is: " + state);
I had the same problem and I found out that you should put the putExtra before you involve the Intent

Please Use FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT

Related

intent.getExtra returns null while passing data from activity to BroadcastReceiver

Intent intent=new Intent(this, AlarmReceiver.class);
intent.putExtra("Test","Test Intent");
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,0,intent,0);
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+2000,pendingIntent);
In BroadcastReceiver onReceive()
String test=intent.getStringExtra("Test");
Intent.getExtra returns null while passing data from activity to BroadcastReceiver? Please help
This is the right way to do it - specify a flag !
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uniqueRequestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

Passing a value with PendingIntent

I am using PendingIntent. I need to pass a value. Intent uses putExtra. Is there an equivalent for PendingIntent? If yes, please provide sample example. Thanks in advance.
I am using:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
Just put the extras in the original intent, i.e.
Intent i = new Intent(context, MainActivity.class);
i.putExtra("key1", "the answer");
i.putExtra("key2", 42);
...
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, i, 0);
The "inner" intent is the one your Activity will actually receive. Check the documentation for PendingIntent.getActivity().
Then, in MainActivity.onCreate():
Intent intent = getIntent();
String strValue = intent.getStringExtra("key1");
int intValue = intent.getIntExtra("key2");
...

2 receiver call using single alarm manager object

I have two Broadcast Receivers :
Sending SMS.
Manage notification.
I have to call both receivers at a specified time.
How can i do that?? is it possible?
The code for calling notification alarm is given below:
AlarmManager alarmManager=(AlarmManager) context.getSystemService(context.ALARM_SERVICE);
Intent intent=new Intent(context,specialNotification.class);
Bundle bu=new Bundle();
bu.putString("TITLE", title);
bu.putString("BODY", body);
bu.putInt("ICON", icon);
bu.putLong("TIME", t);
intent.putExtras(bu);
//Toast.makeText(context, ""+_id, 3000).show();
//Toast.makeText(context, "REpeat Alarm", 3000).show();
PendingIntent pi=PendingIntent.getBroadcast(context, _id, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, t, MILLISECONDS_IN_YEAR, pi);
Please help me to call SMS receiver
Thanks in advance..
You can implement the two reciver by calling the SMS recivers and from the SMS reciver you can create a notification.
I believe you can create a new Intent for your SMS broadcast receiver, and PendingIntent, passing it a different id value than the one you passed to the PendingIntent of your notification.
AlarmManager alarmManager=(AlarmManager) context.getSystemService(context.ALARM_SERVICE);
Intent notifIntent = new Intent(context,specialNotification.class);
Intent smsIntent = new Intent(context,Your_SMS_Receiver.class);
Bundle bu=new Bundle();
bu.putString("TITLE", title);
bu.putString("BODY", body);
bu.putInt("ICON", icon);
bu.putLong("TIME", t);
intent.putExtras(bu);
PendingIntent notifPI = PendingIntent.getBroadcast(context, NOTIFICATION_ID, notifIntent, 0);
PendingIntent smsPI = PendingIntent.getBroadcast(context, SMS_ID, smsIntent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, t, MILLISECONDS_IN_YEAR, notifPI);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, t, MILLISECONDS_IN_YEAR, smsPI);

Widget sending multiple types of intents

I am building a widget that has multiple buttons, each one sending off its own intent to a broadcast receiver. The broadcast receiver is suppose to display a Toast message based on which button was pushed. The code currently looks like this:
public class WidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
ComponentName thisWidget = new ComponentName(context, WidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// Set the text of the buttons
remoteViews.setTextViewText(R.id.widgetPreset1Button, prefs.getString("widget1", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset2Button, prefs.getString("widget2", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset3Button, prefs.getString("widget3", "Not set"));
remoteViews.setTextViewText(R.id.widgetPreset4Button, prefs.getString("widget4", "Not set"));
// Register the buttons with an OnClick event
Intent intent1 = new Intent("myapp.SendWidgetPreset");
intent1.putExtra("Widget", 1);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset1Button, pendingIntent1);
Intent intent2 = new Intent("myapp.SendWidgetPreset");
intent2.putExtra("Widget", 2);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset2Button, pendingIntent2);
Intent intent3 = new Intent("myapp.SendWidgetPreset");
intent3.putExtra("Widget", 3);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset3Button, pendingIntent3);
Intent intent4 = new Intent("myapp.SendWidgetPreset");
intent4.putExtra("Widget", 4);
PendingIntent pendingIntent4 = PendingIntent.getBroadcast(context, 0, intent4, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset4Button, pendingIntent4);
new WidgetBroadcastReceiver();
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
}
and the BroadcastReceiver:
public class WidgetBroadcastReceiver extends BroadcastReceiver{
public WidgetBroadcastReceiver(){
}
#Override
public void onReceive(Context context, Intent arg1) {
int widget = arg1.getIntExtra("Widget", -1);
Toast.makeText(context, "Widget pressed: " + widget, Toast.LENGTH_SHORT).show();
}
}
My problem is it always displays Widget pressed: 4 regardless of which button is pressed. If I put the four lines intent4, intent4.putExtra(), pendingIntent4, and remoteViews.setOnClickPendingIntent() above all of the other intents, it will then always say Widget pressed: 3. In other words, whatever the last intent registration is, that is the widget displayed in the Toast message.
Anyone know why this isn't working how I want it?
you need to provide seperate request code for each pendingintent ex:
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 1/*request code*/, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
Your PendingIntents are being overwritten by the next one. THis is because they compare the Intent being encapsulated, and extras are not considered when comparing Intents. Do this for each intent:
Intent intent1 = new Intent("myapp.SendWidgetPreset");
intent1.putExtra("Widget", 1);
// This line makes your intents different
intent1.setData(Uri.parse(intent1.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetPreset1Button, pendingIntent1);
Seems like PendingIntent.getBroadcast() will ignore requestCode (unlike PendingIntent.getActivity).
Thus, to make unique PendingIntents you could supply Data for the Intent.
Example:
public static Intent makeUniqueIntent(String action, int requestCode) {
Intent intent = new Intent(action);
intent.setData(Uri.parse("http://"+ String.valueOf(requestCode)));
return intent;
}
Then make your Pending Intent as per usual, including the requestCode.
PendingIntent.getBroadcast(ctx, request_code,
makeUniqueIntent(NotificationReceiver.INTENT, request_code),
PendingIntent.FLAG_CANCEL_CURRENT);
With a Data element in an Intent, a matching Intent Filter within AndroidManifest.xml must also have a Data element:
<receiver android:name=".service.NotificationReceiver">
<intent-filter>
<action android:name="my.package.my_action_string"/>
<data android:scheme="http"/>
</intent-filter>
</receiver>
The above intent-filter works as only a scheme (i.e. "http") was identified. So any Uri with that scheme will match this filter's "data" element and the corresponding Receiver class will be called.
Notes:
NotificationReceiver is my class, extending BroadcastReceiver
NotificationReceiver.INTENT is a String constant I declared in NotificationReceiver. In this example it would equal "my.package.my_action_string";
request_code can be anything. Make it unique & save it if you want to reference this same Pending Intent in the future (say for canceling an alarm that uses it).
More info on Data test with Intent Filters:
http://developer.android.com/guide/components/intents-filters.html#DataTest

Trouble sending Bundle with PendingIntent to a Broadcast Receiver, data lost

I am adding some basic alarm functionality to my program via the use of AlarmManager and a BroadcastReceiver class (named AReceiver.java). My problem is that the data I add to the bundle attached to the Intent creating the PendingIntent appears to be lost. The only bundle data I can access in the AReceiver class is a android.intent.extra.ALARM_COUNT=1.
Here is the basic code in the main activity class creating the Intent, PendingIntent and the AlarmManager:
[Code in main activity - Notepadv3]
Intent intent = new Intent(Notepadv3.this, AReceiver.class);
intent.putExtra("teststring","hello, passed string in Extra");
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, pendingPeriodIntentId, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, timeOfNextPeriod.getTimeInMillis(), alarmIntent);
[Code in the BroadcastReceiver - AReceiver]
public void onReceive(Context con, Intent arg1) {
Bundle extrasBundle = arg1.getExtras();
Log.d("broadcast","contains teststring = " + extrasBundle.containsKey("teststring"));
Log.d("broadcast","is empty? = " + extrasBundle.isEmpty());
Log.d("broadcast","to string = " + extrasBundle.toString());
}
Debug messages say that contains teststring is FALSE, is empty is FALSE and when outputting the whole bundle, I get the android.intent.extra.ALARM_COUNT=1 value.
Any help would be greatly appreciated.
Cheers,
Tom
You have to change this line
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, pendingPeriodIntentId, intent, 0);
into this
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, pendingPeriodIntentId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
otherwise the data is lost

Categories

Resources