Notification Button click - method call - android

I've created a Notification to be displayed on Status Bar.
In the notification I've added a Button, which performs some action.
To call a specific method, on button click I'm using the approach suggested here.
Code:
// Building notification - this code is present inside a Service
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent activityIntent = new Intent(this, HomeActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, activityIntent, 0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this).setContentTitle(fileName.toString()).setContentText("Subject")
.setSmallIcon(R.drawable.ic_app_icon).setContentIntent(pendingIntent).setAutoCancel(false);
// code to add button
Intent openListIntent = new Intent();
openListIntent.putExtra("list_intent", true);
PendingIntent listPendingIntent = PendingIntent.getActivity(this, 0, openListIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(R.drawable.ic_open_list, "List", listPendingIntent);
Notification notification = notificationBuilder.build();
// Code in HomeActivity.java to perform operation on button click
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
boolean openListFlag = intent.getBooleanExtra("list_intent", false);
if (openListFlag) {
// code to perform operation
}
}
My approach is that I've passed an Extra boolean value, which is set to true, when button in notification is clicked.
But even if click on only the notification (and not on the button), still the action present in onNewIntent() is getting called.
That is, value for openListFlag is always setted as true.
How should I make sure, that operation is performed only on button click?

Just use intent action instead of extras, as suggested here:
Determine addAction click for Android notifications

Related

Need to dismiss the notification on tap when App is in foreground - android

Im testing the push notification with my app.
when App in the foreground:
Step 1. Received the notification (in system tray).
2. now, I'm in some other screen than the home screen.
3. Actual Problem: On tap on the notification, it is going to the home screen.
4. Expected: If the app is in the foreground, just I need to cancel on tap of the notification. (No need to swipe.)
when App in background/killed: (Works well)
Step 1. Received the notification (in the system tray)
2. On tap, open the home screen of the app.
Tried with setting launch mode flags in intent. Not helped. Below is my code. Please suggest the solution guys.
Intent resultIntent = new Intent(this, MainActivity.class);
//resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
mBuilder.setContentTitle(title);
mBuilder.setContentText(body);
mBuilder.setAutoCancel(true);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(body));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mBuilder.setChannelId(TestUtils.creatChanel(this).getId());
}
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(642, mBuilder.build());
Not sure about dismiss notification on tap, but since your concern is wrong navigation.
We can check app is in foreground or not and prevent new activity to be opened from notification click, if app is in foreground.
//If app is in foreground setting pending intent to null
PendingIntent pendingIntent;
Intent notificationIntent = new Intent(getApplicationContext(), Main2Activity.class);
if(isAppInForeground()){
Log.e("--^","inForeground");
pendingIntent = null;
}else{
Log.e("--^","inBackground");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Add this function (SOURCE: link)
private boolean isAppInForeground() {
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> services = activityManager.getRunningAppProcesses();
boolean isActivityFound = false;
if (services.get(0).processName
.equalsIgnoreCase(getPackageName()) && services.get(0).importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
isActivityFound = true;
}
return isActivityFound;
}
In this case if notification came when app is in foreground, it will do nothing if clicked. So user has only one option left to swipe it to remove.
You can create Custom Notification with close button to close notification using RemoteViews
// create Notification with RemoteViews:
RemoteViews remoteViews= new RemoteViews(getApplicationContext().getPackageName(), R.layout.your_custom_notification);
Intent closeIntent = new Intent(context, CloseNotificationService.class);
hangUpIntent.setAction("close");
PendingIntent pendingCloseIntent = PendingIntent.getBroadcast(this, 0, closeNotification, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.cancel_notification, pendingCloseIntent);
// create notification here..
Notification customNotification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(remoteViews)
.build();
OnClick of close button it will redirect to service class:
public class CloseNotificationService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public CloseNotificationService() {
super("notificationIntentService");
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
switch (intent.getAction()) {
case "close":
Handler hangUpHandler = new Handler(Looper.getMainLooper());
hangUpHandler.post(new Runnable() {
#Override
public void run() {
NotificationManager notifManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifManager.cancel(notificationId); // get notification id from intent.
}
});
break;
}
}
}
For more information of RemoteViews you can refer official google developer website https://developer.android.com/training/notify-user/custom-notification
Instead of this:
Intent resultIntent = new Intent(this, MainActivity.class);
do this:
Intent resultIntent = getPackageManager().getLaunchIntentForPackage("your.package.name");
and put that in your Notification. This will launch the app if it is not already running, otherwise it will just bring the app's task to the foreground in whatever state it was when the user last used it. If the user is already in the app (ie: on another screen), this will do nothing when the user clicks the Notification.
Should be exactly what you are looking for.
Inside your launcher activity have you tried notification manager class cancelAll() method??
In this way if there is already a notification on launch then it will cancelled automatically

Notification is not being dismissed (Android)

Notification setAutoCancel(true) doesn't work if clicking on Action
I have a notification with an action within it. When I tap on the notification it gets removed from the list. However, when I click on the Action it successfully completes the Action (namely makes a call), but when I return to the list of notifications, it remains there.
Relative code of the AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
Meeting meeting;
/**
* Handle received notifications about meetings that are going to start
*/
#Override
public void onReceive(Context context, Intent intent) {
// Get extras from the notification intent
Bundle extras = intent.getExtras();
this.meeting = extras.getParcelable("MeetingParcel");
// build notification pending intent to go to the details page when click on the body of the notification
Intent notificationIntent = new Intent(context, MeetingDetails.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntent.putExtra("MeetingParcel", meeting); // send meeting that we received to the MeetingDetails class
notificationIntent.putExtra("notificationIntent", true); // flag to know where the details screen is opening from
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
// build intents for the call now button
Intent phoneCall = Call._callIntent(meeting);
if (phoneCall != null) {
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, 0, phoneCall, PendingIntent.FLAG_CANCEL_CURRENT);
int flags = Notification.FLAG_AUTO_CANCEL;
// build notification object
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Notification notification = builder.setContentTitle("Call In")
.setContentText(intent.getStringExtra("contextText"))
.setTicker("Call In Notification")
.setColor(ContextCompat.getColor(context, R.color.colorBluePrimary))
.setAutoCancel(true) // will remove notification from the status bar once is clicked
.setDefaults(Notification.DEFAULT_ALL) // Default vibration, default sound, default LED: requires VIBRATE permission
.setSmallIcon(R.drawable.icon_notifications)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(meeting.description))
.addAction(R.drawable.icon_device, "Call Now", phoneCallIntent)
.setCategory(Notification.CATEGORY_EVENT) // handle notification as a calendar event
.setPriority(Notification.PRIORITY_HIGH) // this will show the notification floating. Priority is high because it is a time sensitive notification
.setContentIntent(pIntent).build();
notification.flags = flags;
// tell the notification manager to notify the user with our custom notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
}
}
use this flag:
Notification.FLAG_AUTO_CANCEL
inside this:
int flags = Notification.FLAG_AUTO_CANCEL;
Notification notification = builder.build();
notification.flags = flags;
Documentation
Ok turns out it's a known problem already, and it needs extra code to be done (keeping reference to notification through id). Have no clue why API does not provide this, as it seems very logical to do. But anyways,
see this answer in stackoverflow:
When you called notify on the notification manager you gave it an id - that is the unique id you can use to access it later (this is from the notification manager:
notify(int id, Notification notification)
To cancel, you would call:
cancel(int id)
with the same id. So, basically, you need to keep track of the id or possibly put the id into a Bundle you add to the Intent inside the PendingIntent?
I faced this problem today, and found that FLAG_AUTO_CANCEL and setAutoCanel(true), both work when click on notification,
but not work for action click
so simply, in the target service or activity of action, cancel the notification
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancelAll();
or if have more notification
manager.cancel(notificationId);
You have created two pending intent use in boths and change Flag too.
PendingIntent pIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), notificationIntent, 0);
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), phoneCall, PendingIntent.FLAG_UPDATE_CURRENT);
// CHANGE TO THIS LINE
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
PendingIntent phoneCallIntent = PendingIntent.getActivity(context, 0, phoneCall, PendingIntent.FLAG_CANCEL_CURRENT);

How do I update Activity with intents passed via Notification

I have created a custom notification, but when i pause the activity with the home button and a notification arrives, i press the notification and it creates a new activity and doesnt resume the previews activity and when i press the back button it goes to the previews one which is the same window. I have tried singleTop, singleTask, singleIntent, it works but it doesnt update the activity when a message enters, it is like the previews activity was in pause. how can i fix it?
if there is no solution i though in resuming the activity or destroy the paused activity or maybe restart the activity, is there a way to do this?
public void CustomNotification(String strtext) {
// Using RemoteViews to bind custom layouts into Notification
RemoteViews remoteViews = new RemoteViews(getPackageName(),
R.layout.customnotification);
// Set Notification Title
String strtitle = getString(R.string.customnotificationtitle);
// Open NotificationView Class on Notification Click
Intent intent = new Intent(this, NotificationView.class);
// Send data to NotificationView Class
intent.putExtra("title", strtitle);
intent.putExtra("text", strtext);
intent.putExtra("String T", "");
//intent.putExtra("Integer C", 0);
// Open NotificationView.java Activity
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
// Set Icon
.setSmallIcon(R.drawable.ic_launcher)
// Set Ticker Message
.setTicker(getString(R.string.customnotificationticker))
// Dismiss Notification
.setAutoCancel(true)
// Set PendingIntent into Notification
.setContentIntent(pIntent)
// Set RemoteViews into Notification
.setContent(remoteViews);
// Locate and set the Image into customnotificationtext.xml ImageViews
remoteViews.setImageViewResource(R.id.imagenotileft,R.drawable.ic_launcher);
remoteViews.setImageViewResource(R.id.imagenotiright,R.mipmap.ic_action_chat);
// Locate and set the Text into customnotificationtext.xml TextViews
remoteViews.setTextViewText(R.id.title,getString(R.string.customnotificationtitle));
remoteViews.setTextViewText(R.id.text, strtext);
// Create Notification Manager
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Build Notification with Notification Manager
notificationmanager.notify(0, builder.build());
}
LOGS:
04-29 01:29:10.453 29001-29001/com.example.example E/STATE﹕NEW ACTIVITY
04-29 01:29:15.376 29501-29501/com.example.example D/Activity﹕ Activity.onPause(), editTextTapSensorList size: 0
04-29 01:30:06.981 29501-29501/com.example.example E/STATE﹕ RESUMING
WHEN I PRESS THE NOTIFICATION:
04-29 01:33:09.654 33449-33530/com.example.example E/STATE﹕NEW ACTIVITY
I will appreciate any answer, Thanks!
EDITED
ANSWER:
the answer was to add:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
because when i was in the same window and i pressed the home button, the activity was in paused, then if some notification arrived it brought me to that window but didnt updated the messages so I needed to create a new intent and erase the previous one which was in pause. so that code did the Job.
To update your activity, you should override onNewIntent():
protected void onNewIntent (Intent intent) {
super.onNewIntent(intent);
//reload your data here
}
Android Docs say:
void onNewIntent (Intent intent)
This is called for activities that set launchMode to "singleTop" in
their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag
when calling startActivity(Intent). In either case, when the activity
is re-launched while at the top of the activity stack instead of a new
instance of the activity being started, onNewIntent() will be called
on the existing instance with the Intent that was used to re-launch
it.
An activity will always be paused before receiving a new intent, so
you can count on onResume() being called after this method.
Note that getIntent() still returns the original Intent. You can use
setIntent(Intent) to update it to this new Intent.
Note: as the docs say, you need to set android:launchMode="singleTop" in your Activity tag (in AndroidManifest).
try this in your service code to use notification :
private static final int NOTIFY_ME_ID = 1222;
NotificationManager mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
private void Notifi(String message){
int requestID = (int) System.currentTimeMillis();
Intent intent = new Intent(Intent.ACTION_MAIN);
//CLEAR PREVIOUS ACTIVITIES AND CREATE A NEW ONE
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName("packagenameofyourapplication",
"packagenameofyourapplication.NotificationView"));
PendingIntent pintent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notif = new Notification.Builder(this)
.setContentTitle(getString(R.string.notification_titel)).setContentText(message)
.setSmallIcon(R.drawable.ic_launcher).setAutoCancel(true)
.setContentIntent(pintent).build();
notif.flags = Notification.FLAG_NO_CLEAR;
mNotificationManager.notify(NOTIFY_ME_ID, notif);
}

onclicklistener for notification [duplicate]

This question already has answers here:
How to set click listener for notification?
(3 answers)
Closed 9 years ago.
I had set a notification in my app. Its working fine. If i click the notification in statusbar it takes to my app.
Now i need to set some work if the notification is clicked where can i set this?
Is there any method that implicitly got invoked when a notification is clicked?
Also i want to remove that notification if it is clicked,how to do so?
this is my code
notifManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent inty=getIntent();
note = new Notification(R.drawable.icon, "New E-mail", System.currentTimeMillis());
PendingIntent intent = PendingIntent.getActivity(MainActivity.this, 0, inty, 0);
note.setLatestEventInfo(MainActivity.this, "New E-mail", "You have one unread message.", intent);
notifManager.notify(R.string.search_hint, note);
You could add some extra data to the intent and then in your activity look for it in the onCreate and onNewIntent methods.
For example:
inty.putExtra("came from notification", true);
You can then read that out via the intent passed to onNewIntent or in onCreate by using getIntent().
intent.getBooleanExtra("came from notification", false);
Try to call broadcastReceiver it may helpful for your requirement,
Intent notificationIntent = new Intent(this, dummy_activity.class);
notificationIntent.setAction("android.intent.action.MAIN");
notificationIntent.addCategory("android.intent.category.LAUNCHER");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT |
Notification.FLAG_AUTO_CANCEL);
// Now, once this dummy activity starts send a broad cast to your parent activity and finish the pending activity
//remember you need to register your broadcast action here to receive.
BroadcastReceiver call_method = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action_name = intent.getAction();
if (action_name.equals("call_method")) {
// call your method here and do what ever you want.
}
}
};
registerReceiver(call_method, new IntentFilter("call_method"));

Determine if Activity is called by a Notification

I am using an Activitiy with various Tabs on it. From a different part of the application, Notifications are created to tell the user that something has changed. I now managed to Call the Activity, when the user clicks on the Notification. But how can i determine wheter a Activity is created the "normal" way during runtime or by clicking on the notification?
(Depending on the notification clicked, i want to forward to another tab instead of showing the main Tab.)
Intent intent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, intent, 0);
// TODO: Replace with .Build() for api >= 16
Notification noti = new Notification.Builder(ctx)
.setContentTitle("Notification"
.setContentText(this.getName())
.setSmallIcon(R.drawable.icon)
.setContentIntent(pendingIntent)
.setDefaults(
Notification.DEFAULT_SOUND
| Notification.DEFAULT_LIGHTS)
.setAutoCancel(true)
.getNotification();
NotificationManager notificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
// Hide the notification after its selected
notificationManager.notify(this.getId(), noti);
This successfully calls my MainActivity. But is there some Method that is called when the Activity is triggered by the pendingIntent?
Thought about to define something like this in the Main Activity:
onTriggeredByNotification(Notification noti){
//determinte tab, depending on Notification.
}
Pass a boolean value from notification and check for the same in the onCreate method of the activity.
Intent intent = new Intent(ctx, MainActivity.class);
intent.putExtra("fromNotification", true);
...
if (getIntent().getExtras() != null) {
Bundle b = getIntent().getExtras();
boolean cameFromNotification = b.getBoolean("fromNotification");
}
You can try this in your Notification
Intent intent=new Intent();
intent.setAction("Activity1");
In the Activity override onNewIntent() method and get action so you can determine the activity is called or not.
Better than using the reserved action field of your intent as specified by #ricintech, you could use an extra parameter in your pending intent and detect it in your onCreate method and in your onNewIntent metod inside your activity.

Categories

Resources