How to change image on custom notification button click? - android

I have set up a notification for a custom xml and I can successfully register click events.
remoteViews.setOnClickPendingIntent(R.id.notif_button, pendingIntent);
I also have a broadcast receiver that receives the onclick event, no problem there.
As you can see, this event fires once when the user releases the button. I need an event that fires every time when the user touches the button, so I can change it. Like every button in android.
Setting selectors in xml did not work. I tried this example:
https://developer.android.com/reference/android/widget/ImageButton.html
It should be possible, since some music players implemented this behaviour. Any ideas to achieve that?

As you can see, this event fires once when the user releases the button.
That's because that's what is considered a "click" -> touch down and then touch up on the same object. If you touch a button, keep it on screen but move out of it and release then the click won't be fired. That's why it works that way.
I need an event that fires every time when the user touches the button
You cannnot have this. Luckily.
Setting selectors in xml did not work
Selectors are not for this.

private NotificationTarget notificationTarget;
notificationTarget = new NotificationTarget(
context,
R.id.remoteview_notification_icon,
remoteViews,
notification,
NOTIFICATION_ID);
GlideApp
.with(context.getApplicationContext())
.asBitmap()
.load(eatFoodyImages[3])
.into(notificationTarget);
For further reference please visit
https://futurestud.io/tutorials/glide-loading-images-into-notifications-and-appwidgets

Create a custom notification...define your xmls add your selectors and background and create and trigger your notifications.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher);
RemoteViews mContentView = new RemoteViews(getPackageName(), R.layout.test_tt);
mContentView.setImageViewResource(R.id.image, R.drawable.ic_action_search);
mContentView.setTextViewText(R.id.title, "Custom notification");
mContentView.setTextViewText(R.id.text, "This is a custom layout");
mBuilder.setContent(mContentView);
notimgr.notify(1001, mBuilder.build());
let me know if any issues.
Best Regds

Related

How to hook up click on Notification group?

Is it possible to override or create listener for click on Notification Group? I can't find any information or documentation about this. I know how to set PendingIntent to single notification but not for group. Is there any way to do this?
To be able to a specific behavior when the user clicks the notification group you can create a group summary and add a PendingIntent to it.

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
}
}

Add <fragment> in notification layout?

I'm developping a music player application for android and I'm stuck with a problem in the notification layout. It seems like I can't add any complicated element in it or it throws android.app.RemoteServiceException: Bad notification.
Problem is I wrote a player controller that is a Fragment. I can't find how to add the fragment by hand in code so I tried directly in XML layout but without success. I also had the problem with a custom ImageView that I wrote.
Am I really obliged to duplicate code ?
It does not look like you can add a fragment. You could see if MediaStyle fits your needs. In your notification builder you would add .setStyle(NotificationCompat.MediaStyle). Otherwise it looks like you would have to subclass Notification.Style or NotificationCompat.Style to create a custom layout. It also looks like for some options you can intercept the notification as it's being created. Check this out for more details.
Edit:
Given your time frame, and if you're willing to flex some on your layout, then I would just add buttons to the notification. Create a pending intent for each action you want to be able to do from your notification (play, pause, skip). By way of a code sample I've included an abbreviated version of how I put a dismiss button in my notifications.
Intent resultIntent = new Intent(context, AlarmScreen.class);
resultIntent.putExtra("Id",reminder.getId());
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
reminder.getId()*2,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
Notification.Builder mBuilder =
new Notification.Builder(context)
.setStyle(new Notification.BigTextStyle()
.bigText(reminder.getDescription()))
.addAction(R.drawable.ic_stat_content_clear, "Dismiss", dismissPendingIntent)
.build();
In your case you should be able to replace the R.drawable.ic_stat_content_clear with an appropriate icon and maybe skip the text. You can just repeat .addAction() for each button you want. Notice also where I have reminder.getId()*2 in my pending intent declaration? I found that if I had the same number there for both of my buttons I got strange results, so one of my buttons has id*2 and the other has id*2+1.
As for how you handle the intents sent by the buttons, you'll have to create a BroadcastReceiver to receive them, and figure out where to go from there based on how you're implementing the rest of your logic.
That is not possible. Notification only able to use with RemoteView. RemoteView support some views only, and it do not support custom views or fragment.

How to find that notification view is expanded or not

I am using the following code showing the notification, it works properly. I am look for the listener from which i can come to know whether the notification is expanded or not.
I want to open the app if the notification is expanded or else open the particular activity of the app.
Intent intent= new Intent(context, Activity1.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, getNextRandom(), intent, 0);
Builder newBuilder newBuilder = new Notification.Builder(context);
newBuilder.setContentTitle(title)
.setContentText(subtitle)
.setAutoCancel(true)
.setSmallIcon(R.drawable.icon)
.setTicker(notificationMessage)
.setContentIntent(pendingIntent);
Notificationnotification = new Notification.BigTextStyle(newBuilder)
.setBigContentTitle(notificationTitle)
.bigText(text)
.build();
Let me know if there is way to acheive this?
There is no way to know if the notification is open... What you can do is add buttons to the expanded notification that pressing on them will act differently than pressing on the notification itself.
There maybe no direct way, but maybe the following hack can help!!
You can have a custom notification layout and use RemoteView, Set a setOnClickPendingIntent to launch a service for the entire view so that you get notified when the notification is clicked.
When the user clicks the notification, service is started and show the new expanded custom layout from the service (you replace the old notification with the new one)
Maybe show your initial notification also from the same service using startforeground, so that your app is not killed and the view click can be received faster since service is already running and response time for changing the view is lower.
see this for remoteview and this for launching service from notification click.

Status bar Notification in android

I want to set a onClickListner for a status bar Notification. How it is possible ? Please help. Now i can load a Activity by using the pending intent. I like to set a onClickListner for the notificatioin.
Regards
Parvathi
It is not possible to set an OnClickListener for a notification. Because of the way notifications are handled/displayed there is no way to guarantee that the process that created the notification will be running at the time the notification is clicked. This means that any code you wrote to provide click handling may not be running.
If you need click listener style behavior you will have to do it using the PendingIntent: set it to start a Service that runs the logic or to use an Intent that is received by a BroadcastReceiver. This will let you perform activity without requiring a UI.

Categories

Resources