I have built a notification and am displaying it properly, but I can't figure out how to pass data to the activity. I pulled one string from the intent to display as the title of the notification, but I need to pull a 2nd string, and have the NotificationHandlerActivity process it.
//inside intentservice
private void sendNotification(Bundle extras) {
Intent intent=new Intent(this, NotificationHandlerActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("link", extras.getString("link"));
mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
long[] vibrate = {100L, 75L, 50L};
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.abc_ic_menu_copy_mtrl_am_alpha)
.setContentTitle(extras.getString("title"))
.setOngoing(false)
.setAutoCancel(true)
.setVibrate(vibrate);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
//Inside NotificationHandlerActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
}
You should use the extras on your Intent. Because your intent is currently anonymous, you cannot do so. Extras are basic key-value stores. See below:
public static final String KEY_SECOND_STRING = "keySecondString";
...
...
String secondString = "secondString";
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, NotificationHandlerActivity.class);
intent.putExtra(KEY_SECOND_STRING, secondString);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
...
then, from your NotificationHandlerActivity, you can access that secondString from the intent.
#Override
public void onCreate(Bundle sIS){
super.onCreate();
String secondString = getIntent().getStringExtra("keySecondString");
...
}
use it like this :
Intent intent=new Intent(this, NotificationHandlerActivity.class);
intent.putExtra("key", "value");
mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
long[] vibrate = {100L, 75L, 50L};
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.abc_ic_menu_copy_mtrl_am_alpha)
.setContentTitle(extras.getString("title"))
.setOngoing(false)
.setAutoCancel(true)
.setVibrate(vibrate);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Apparently using 0 as the requestCode when calling getActivity() on the PendingIntent isn't the way to go. I updated it to just use System.currentTimeMillis() and that seemed to work. I'm assuming that the first time I built the notification, using 0 as the requestCode, the extra wasn't present.
Related
I am adding functionality to receive push notifications in Android. I have added a subclass of GcmListenerService and have overriden the onMessageReceived method and am building a notification with action buttons. My code is as follows:
GCMListenerService
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, PushActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("pushMessage", message);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Intent acceptIntent = new Intent(this, GcmBroadcastReceiver.class);
acceptIntent.putExtra("pushMessage", message);
acceptIntent.putExtra("action", Constants.ACTION_ACCEPT);
acceptIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent acceptPendingIntent = PendingIntent.getBroadcast(this, 0, acceptIntent, 0);
Intent denyIntent = new Intent(this, GcmBroadcastReceiver.class);
denyIntent.putExtra("action", Constants.ACTION_DENY);
denyIntent.putExtra("pushMessage", message);
denyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent denyPendingIntent = PendingIntent.getBroadcast(this, 0, denyIntent, 0);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Authenticator")
.setContentText("You have initiated a transaction")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(NotificationCompat.PRIORITY_MAX)
.addAction(R.drawable.ic_media_play, "Accept", acceptPendingIntent)
.addAction(R.drawable.ic_media_pause, "Deny", denyPendingIntent)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
The issue which I am facing is that no matter what notification I send, I am receiving the same message always when I try to use the action buttons. When I try to open the activity, the correct messages gets read. I am reading the message in the GcmBroadcastreceiver and it is always the same. It seems that the intent is the same and does not get recreated. Is there something I am doing wrong?
I'm trying to putExtra to Activity which will be launched after clicking on notification, but instead of value that I set I'm getting default value. This is my code in AlarmReceiver:
Intent notifActiv = new Intent(context, NotificationActivity.class);
notifActiv.putExtra("ID", id);
PendingIntent pI = PendingIntent.getActivity(context, 0, notifActiv, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(string).setTicker("You got meeting today!")
.setContentText("Click here for more details");
mBuilder.setContentIntent(pI);
mBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE);
mBuilder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, mBuilder.build());
And this is my NotificationActivity where I'm trying to get Extras:
Intent intent = getIntent();
int id = intent.getIntExtra("ID", 0);
Could you please tell my where I'm doing something wrong?
I have prepared a simple test app which posts a notification on a button click:
The source code from MainActivity.java creating the notification is displayed below:
Button showButton = (Button) findViewById(R.id.show);
showButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent appIntent = new Intent(mContext, MainActivity.class);
appIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
appIntent.putExtra("my_data", 12345);
String question = getString(R.string.the_question);
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(mContext)
.setContentTitle(question)
.setContentText(question)
.setTicker(question)
.setWhen(System.currentTimeMillis())
.setContentIntent(contentIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
mManager.notify(NOTIFY_ID, notification);
}
});
My question is: how to modify the notification, so that the user is asked a Yes/No question (in this case: "Do you want to open the car?") and - after she selects Yes or No to launch the same app and run a corresponding method in it (in this case: openCar() or closeCar() method).
I probably should use NotificationCompat.Action.Builder - but how exactly?
Also I am not really sure if this code is the correct code for launching an app from notification and what flags should I use:
Intent appIntent = new Intent(mContext, MainActivity.class);
appIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
And finally I wonder if hardcodidng some random number in NOTIFY_ID is the correct way when posting notifications?
Here is a source code I used for notification with Login/Register action.
private void sendNotification(String message, String title) {
try {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Intent secondActivityIntent = new Intent(this, SecondActivity.class);
PendingIntent secondActivityPendingIntent = PendingIntent.getActivity(this, 0 , secondActivityIntent, PendingIntent.FLAG_ONE_SHOT);
Intent thirdActivityIntent = new Intent(this, ThridActivity.class);
PendingIntent thirdActivityPendingIntent = PendingIntent.getActivity(this, 0 , thirdActivityIntent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_3d_rotation_white_36dp)
.setContentTitle(title)
.setContentText(message)
.addAction(R.drawable.ic_lock_open_cyan_600_24dp,"Login",secondActivityPendingIntent)
.addAction(R.drawable.ic_lock_pink_700_24dp,"Register",thirdActivityPendingIntent)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
To use it: simply call this method sendNotification(String yourMessage, String yourTitle)
e.g. sendNotification("Hello Message", "Hello Title")
Here is a snapshot of the output
Notify user on pending Intent.. an example is here..
public void notifyUser() {
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(HappyActivity.this, NotificationDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// use the flag FLAG_UPDATE_CURRENT to override any notification already
// there
pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification(R.drawable.ic_launcher,
"Question.....?????", System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL
| Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND;
notification.setLatestEventInfo(this, "title",
"Explanation of question..", pendingIntent);
// 10 is a random number I chose to act as the id for this notification
notificationManager.notify(10, notification);
}
I try to make notification, but click on notification does not work as expected: in activity I could not retrive additional info send in notification:
int requestID = (int) System.currentTimeMillis();
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, LoadPictureActivity.class);
intent.putExtra("Test", "sometext");
PendingIntent pIntent = PendingIntent.getActivity(this, requestID, intent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.common_signin_btn_icon_focus_light)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setContentIntent(pIntent)
.setAutoCancel(true);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
In LoadPictureActivity`s onCreate method I try to catch additional info:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
Log.d("App", "Intent get intent: " + intent);
if (intent != null) {
Log.d("App", "Intent extra sting: " + intent.getStringExtra("Test"));
}
}
But after click on notification I do not see any output with additional string, I also try to put the same check in OnResume, but in this case after click on notification I see that fires the intent that original start main class with nullable extra string. So I'm not sure if notification click works correctly in total. Where is the problem?
Try this way
PendingIntent pIntent = PendingIntent.getActivity(this, requestID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Below is my block of code which should open NotificationActivity when the notification is tapped on. But its not working.
private void setNotification(String notificationMessage) {
Uri alarmSound = getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mNotificationManager = getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(getApplicationContext(), NotificationActivity2.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.logo)
.setContentTitle("My Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notificationMessage))
.setContentText(notificationMessage).setAutoCancel(true);
mBuilder.setSound(alarmSound);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
try this:
private void setNotification(String notificationMessage) {
//**add this line**
int requestID = (int) System.currentTimeMillis();
Uri alarmSound = getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mNotificationManager = getApplication().getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(getApplicationContext(), NotificationActivity2.class);
//**add this line**
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
//**edit this line to put requestID as requestCode**
PendingIntent contentIntent = PendingIntent.getActivity(this, requestID,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.logo)
.setContentTitle("My Notification")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notificationMessage))
.setContentText(notificationMessage).setAutoCancel(true);
mBuilder.setSound(alarmSound);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
You might be using a notification id equal to 0. There is known issue with notification id being 0. If you will use any other id, it should work.
I added task builder and the below block code worked for me
Intent intent = new Intent(context, HomeActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(SplashActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Try checking your AndroidManifest.xml, double check if you are navigating to an activity with an intent-filter main action, launcher category
For example,
I couldn't make my pending intent to navigate to HomeActivity but it works when navigating to SplashScreen
Hope this helps.
If the app is already running then you need to handle it in onNewIntent
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//Handle intent here...
}
Added the requestid, but the intent was still not opening.
This is the solution that worked for me:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Setting those flags to clear the activities below the intent activity.