handling multiple buttons on a custom notification bar - android

I have a custom notification bar in my application that has 2 buttons. I found a way to make the buttons work by using contentView.setOnClickPendingIntent in my notification class and then handle the functionality in separate activity but I have a problem. Here is the code in Notification class.
//Handle the button for showing bookmarks on custom notification
Intent buttonsIntent2 = new Intent(context, NotificationBarButtonActivityHandler.class);
buttonsIntent2.putExtra(PENDING_ACTION, REGISTER_BOOKMARK);
contentView.setOnClickPendingIntent(R.id.notificationBarShowBookmarksButton, PendingIntent.getActivity(context, 0, buttonsIntent2, 0));
//Handle the button for adding bookmark on custom notification
Intent buttonsIntent = new Intent(context, NotificationBarButtonActivityHandler.class);
buttonsIntent.putExtra(PENDING_ACTION, SHOW_BOOKMARKS);
contentView.setOnClickPendingIntent(R.id.notificationBarAddBookmarkFromChromeButton, PendingIntent.getActivity(context, 0, buttonsIntent, 0));
The problem is that no matter which button is pressed, the button handler activity always receives REGISTER_BOOKMARK when I am pressing both button.
String action = (String) getIntent().getExtras().get(NotificationBarService.PENDING_ACTION);
Could someone please explain to me why is this happening? Also, is this the optimal way to handle button presses in the notification bar?

Related

Handle notification click in background

I have added two action button to the notification but I'm not able to handle the click event in background.
Intent ok = new Intent(mContext, MainActivity.class);
ok.putExtra("OK",true);
PendingIntent intentOK = PendingIntent.getActivity(mContext, 0 , ok, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.ic_ok, delivered(), intentOK);
mBuilder.addAction(R.drawable.ic_ko, notdelivered(), intentKO);
The actions needs an intent that force my app in foreground.
I need to post user choice to a remote server without popping up the app.

Collapsing Notification Panel in Android 12

My app has a notification, that has an action button.
When clicking the button, I want the notification panel (or drawer, you name it) to collapse.
I've found a bunch of solutions, all suggesting the same (one of them for example).
This solution doesn't work anymore, at least not for me (on a Oneplus 8t Android 12 device). When that command is called, the app crashes.
What's the updated way to collapse the notification panel?
I came up with an idea after thinking about this question for months. All you need is an empty activity that doesn't show anything. I think this is a little bit hacky, but I don't have better ideas.
First, create a dummy empty activity that shows nothing, and put the code you would like to do inside that dummy activity.
DummyActivity.class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Do your work here, put the work you would like to do after pressing the button, such as send a broadcast, so your work will still be executed
//No setContentView() is being called, so nothing will be displayed after opening this activity.
finish();
}
Remember to add android:excludeFromRecents="true" for the dummy activity in AndroidManifest.xml so the dummy activity doesn't show in recent apps.
Second, use PendingIntent.getActivity() instead, don't use PendingIntent.getBroadcast(), so you should have something like this :
RemoteViews remoteviews = new RemoteViews(context.getPackageName(), R.layout.notification_layout);
Intent notificationIntent = new Intent(context, DummyActivity.class);
PendingIntent pendingIntent;
pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
remoteviews.setOnClickPendingIntent(R.id.MyButton, pendingIntent);
With this kind of implementation, after clicking the button, the transparent activity will be started, showing nothing but causing the notification panel to be collapsed.

How to prevent notification bar from closing upon notification action click while using PendingIntent.getActivity. Part 2

So in my app i have notification with pause/play action, when user clicks on the action, notification bar is closing. How can i prevent notification bar from closing upon action click?
I've already done .setAutoCancel(false);
Here I've found a "problem":
https://stackoverflow.com/a/53476100/10766642
PendingIntent.getActivity(...) - it closes notification bar.
And yes, I have this lines too:
PendingIntent btn1 = PendingIntent.getActivity(parent, (int)(Math.random()), intent, PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.btn1, btn1);
How can i prevent notification bar closing without using PendingIntent.getService(...) or PendingIntent.getBroadcast(...) ?

Android: How to distinguish CLEAR all events from notification bar from user action

According to the specification, .setDeleteIntent(pendingIntent) is associated to both actions (CLEAR all events from notification bar and user action like swiping).
My requirements are that when the user touches the notification that appears on the notification bar, he must be forwarded to the NotificationsList.class. This is done with my pendingInent:
PendingIntent sendPendingIntent = PendingIntent.getActivity(context, reminderId, new Intent(context, NotificationsList.class), PendingIntent.FLAG_UPDATE_CURRENT);
However, on clicking the CLEAR button, the user must not be navigated to the application at all. With the .setDeleteIntent(pendingIndent) I cannot fulfill the 2nd requirement. The user is still navigated to NotificationsList.class.
Is there a way to programmatically distinguish the CLEAR all notifications events fired from the CLEAR button from user actions like touch or swipe on the specific notification on the notification bar?
What you're describing is very obtuse behavior. You need only set the pending intent to your notification and when it is clicked, the intent that is backing it will be executed.
If your code is navigating the user back to the app when the notification is cleared, then you already have a problem with your design. If the user clears your notification you should NOT be trying to navigate them back. Hence the setDeleteIntent() should NOT be associated with starting any activity.
Note that the intent that is backed when you click the notification (setContentIntent()) and clear (setDeleteIntent()) the notification are basically two PendingIntents, they should not be the same, which is what your problem is describing.
You cannot distinguish the two events. As the documentation says:
Notifications remain visible until one of the following happens:
The user dismisses the notification either individually or by using "Clear All" (if the notification can be cleared).
The user clicks the notification, and you called setAutoCancel() when you created the notification.
You call cancel() for a specific notification ID. This method also deletes ongoing notifications.
You call cancelAll(), which removes all of the notifications you previously issued.
So there are basically three different events in the view of a programmer:
You dismisses the notification
The user clicks on the notification
The user dismisses the notification (either by swiping or clearing it)
The first event is fired by yourself by calling cancelAll() or cancel().
You can handle the second like (which you wanna do I think):
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//....
.setContentIntent(sendPendingIntent);
And you can handle the third event like (as you have described above):
builder.setDeleteIntent(pendingIndent)
I don't recommend to start an activity after the user dismisses your notification, because the user won't expect it and it will be a bad user experience.
I hope I could help.
According to the design guidelines, the user can expect to interact with your notification using higher-level gestures like click, swipe, and pinch zoom. Responding instantly to a lower level event like touch would short circuit these gestures, so your requirements would violate the design guidelines and you should not implement it.
If the requirements are changed so that the user is forwarded when they click on the notification, there is no need to distinguish between swiping and clearing, which is impossible in any case.
So your issue should be resolved by changing one word in the requirements: touch --> click.
I googled deleteIntent to find some info for a problem which led me here.
English is my second language. Sorry for some misuse of words in advance. I'm an android newbie, just downvote the answer if it sucks :)
For your last question, just as #x-code and #bendaf said, it's impossible to
distinguish swiping and clearing.
I am following the codelabs about notifications and encountered the same question(The description in your title). So I decided to offer more detail about how to use .setDeleteIntent in your case. Maybe you had done that.
In your case, the wrapped intent is for starting an activity, so do the pendingIntent.
PendingIntent sendPendingIntent = PendingIntent.getActivity(context, reminderId, new Intent(context, NotificationsList.class), PendingIntent.FLAG_UPDATE_CURRENT);
But for performing a broadcast, e.g. doing some stuff when the notification is cleared, use:
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIFICATION_ID, new Intent(yourCustomActionString), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setDeleteIntent(pendingIntent); // the pendingIntent will be sent when the notification is cleared
Then we need a custom broadcast receiver receive that custom action contained in the Intent object, in your case, this action relates to the clearing:
// Inside onCreate, register the broadcast receiver;
registerReceiver(new MyReceiver(), new IntentFilter(yourCustomActionString));
.
.
// Create an inner class
public class MyReceiver extends BroadcastReceiver {
public NotificationReceiver() {}
#Override
public void onReceive(Context context, Intent intent) {
// code inside will be executed when pendingIntent is sent
Log("taG", "Notification is cleared"); // a message will be logged if the notification is cleared
// for more than one action, using switch...case to decide
}
}

How to close notification drop-down in Android >= 3.0 from custom rich notification with additional button?

I successfully created a custom rich notification for Android >= 3.0 that shows some text and an additional button. If you click the notification anywhere but on the button in the notification drop-down, the notification is dismissed, the drop-down closed and the specified Intent is launched as expected.
If the dedicated button in the notification is clicked, a different Intent is successfully launched, but the drop-down keeps open (and the notification is still there, but I cancel it later, that is not the problem). The Intent launches an Activity which appears behind the notifications drop-down.
What I like to achieve is to keep all the current behavior as described, but also close the notification drop-down from the Intent the button launches - is this possible? Alternatively it would be enough if the Activity from the button Intent gains the window focus.
Here the code for the custom notification, if that helps:
Notification.Builder builder = new Notification.Builder(main)
.setSmallIcon(R.drawable.notification)
.setAutoCancel(true)
.setTicker(text)
.setContentIntent(...);
RemoteViews layout = new RemoteViews(
main.getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.title, title);
layout.setTextViewText(R.id.text, text);
Intent i = new Intent(
"snooze", null, main, Snooze.class
);
i.putExtra(KEY_WIDGET_ID, widgetId);
layout.setOnClickPendingIntent(R.id.notification_zzz, PendingIntent.getActivity( main, 0, i, PendingIntent.FLAG_UPDATE_CURRENT ));
builder.setContent(layout);
...
NotificationManager nm =
(NotificationManager)main.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(0, builder.getNotification());
Asked the question in the Android developer office hours:
http://www.youtube.com/watch?v=XvLBvdml_Fs (question starting 49:10)
The answer was, that it is not possible and I should not even do this, which I question.
That is why I have created a feature request:
http://code.google.com/p/android/issues/detail?id=24762
EDIT 08-10-12:
Starting with Android 4.1 this is possible as notifications can now include additional actions. See the following page for more information:
https://developer.android.com/about/versions/android-4.1.html#UI

Categories

Resources