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?
Related
Okay so what I am doing right now is getting a push notification through FCM that's been going well. Now I'm able to change the activity when application is on foreground, but how do I change it when I tap the notification in notification panel? Need help.
My Code:
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
// on click activity for the notification !!!!!!!!!!
intent = new Intent(Intent.ACTION_MAIN);
intent.setClass(mContext, TestActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
long notificatioId = System.currentTimeMillis();
Intent intent = new Intent(getApplicationContext(), TestActivity.class); // Here pass your activity where you want to redirect.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, (int) (Math.random() * 100), intent, 0);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){
currentapiVersion = R.mipmap.ic_notification_lolipop;
} else{
currentapiVersion = R.mipmap.ic_launcher;
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(currentapiVersion)
.setContentTitle(this.getResources().getString(R.string.app_name))
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setContentIntent(contentIntent);
mNotificationManager.notify((int) notificatioId, notificationBuilder.build());
}
I have used in this manner to start a specific activity:
FireBaseMessagingService.java
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//The message will contain the Push Message
String message = remoteMessage.getData().get("message");
//imageUri will contain URL of the image to be displayed with Notification
String imageUri = remoteMessage.getData().get("image");
//title for the notification.
String title = remoteMessage.getData().get("title");
//action string to perform the action e.g. open activity
String action = remoteMessage.getData().get("click_action");
//To get a Bitmap image from the URL received
bitmap = getBitmapfromUrl(imageUri);
//method for functioning the notification --->
sendNotification(message, title, bitmap, action);
}
private void sendNotification(String messageBody, String title, Bitmap image, String action) {
Intent intent = new Intent(this, SpecificActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("title", title);
ByteArrayOutputStream _bs = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 50, _bs);
intent.putExtra("img", image);
intent.putExtra("msg", messageBody);
intent.putExtra("click_action", action);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new
NotificationCompat.Builder(this, "Default")
.setLargeIcon(image)/*Notification icon image*/
.setSmallIcon(R.mipmap.app_icon)
.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image))/*Notification with Image*/
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_HIGH)
.setChannelId("Default")
.setVibrate(new long[]{1000, 1000})
.setContentIntent(pendingIntent);
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(messageBody);
notificationBuilder.setAutoCancel(true);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
After this Add the following lines in the specificActivity.java part in the AndroidManifest.xml file:
<activity
android:name=".SpecificActivity">
<intent-filter>
<action android:name="OPEN_ACTIVITY" />
<!-- Add this OPEN_ACTIVITY string into your data payload while sending the notification from server side. -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
After this get the intent in the specific activity you are starting i.e. SpecificActivity.java file's onCreate() method.
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet())
{
String value = getIntent().getExtras().getString(key);
if (key.equals("click_action")) {
//perform the action you want to do with the key.
}
After adding these you are good to check the notifications from your mobile end.
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(mContext,ACTIVITY_TO_BE_DISPLAYED.class); // Replace ACTIVITY_TO_BE_DISPLAYED to Activity to which you wanna show
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(mContext, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setAutoCancel(true)
.setTicker("YOUR_TICKER_MSG")
.setSmallIcon(R.drawable.ic_notification_icon)
.setLargeIcon(icon)
.setContentTitle("YOUR_TITLE")
.setContentText("YOUR_TEXT")
.setContentIntent(intent);
notificationManager.notify(10, builder.build());
<!-- MainActivity is the parent for ResultActivity -->
<activity
android:name=".ResultActivity"
/>
Dont forget to adjust Manifest with child activity declaration
Pass your Activity you want to open when clicked into Intent.
Intent notificationIntent = new Intent(context, XYZActivity.class);
complete code:
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, XYZActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
edit: My code worked fine, I was simply giving it the wrong Activity class (multiple APK build project using shared library).
I'm using the following code to display a foreground notification for my Service. For some reason though, it doesn't show me my activity when I click on the notification.
I've checked out various StackOverflow posts and followed accordingly, and even the sample FakePlayer from CommonsWare but to no avail.
protected void updateNotification(String subtitle) {
// The PendingIntent to launch our activity if the user selects this notification
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Show notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_headset_mic)
.setWhen(System.currentTimeMillis())
.setContentTitle("AirWaves: " + G.SETTINGS.deviceName)
.setContentText(subtitle)
.setContentIntent(pendingIntent)
.setOngoing(true);
startForeground(NOTIFICATION_ID, builder.build());
}
Anyone have an idea where I might be going wrong with this?
i have also implement notification consider the following example
public void sendNotification(Context context,String message, String action) {
try {
int icon = R.drawable.notilogoboss;
String title = context.getString(R.string.app_name);
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("message", message);
intent.putExtra("action", action);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.logoboss))
.setSmallIcon(icon)
.setContentTitle(title)
.setWhen(System.currentTimeMillis())
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
int notId = UUID.randomUUID().hashCode();
notificationManager.notify(notId, notificationBuilder.build());
} catch (Exception e) {
}
}
Please try the following method to create the pending intent:
Intent intent = new Intent( context, MainActivity.class );
intent.putExtra( "message", message );
intent.putExtra("action", action);
TaskStackBuilder stackBuilder = TaskStackBuilder.create( context );
stackBuilder.addParentStack( MainActivity.class );
stackBuilder.addNextIntent( intent );
PendingIntent pendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT );
notificationBuilder.setContentIntent( pendingIntent );
Try changing the flag for the pending intent to this:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Also, what is the startForeground(NOTIFICATION_ID, builder.build()); method that you are using? can you post that as well for additional help?
I want to open the activity that gave a notification and the user should be directed to the activity if s/he clicks on it. And the notification should disappear.
use this method for open activity in android
// Notification Method
private void Notification(String notificationTitle,
String notificationMessage) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
android.app.Notification notification = new android.app.Notification(
R.drawable.ic_launcher, "Message from Binesh Kumar! (Android Developer)",
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, AndroidNotifications.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(AndroidNotifications.this,
notificationTitle, notificationMessage, pendingIntent);
notificationManager.notify(10001, notification);
}
1. Create any notification something like
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
2. Now if you want to associate any activity say ResultActivity , create PendingIntent
Intent resultIntent = new Intent(this, ResultActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
3: Set the pending intent to notification builder
mBuilder.setContentIntent(resultPendingIntent);
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);
}
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.