I have created a custom layout notification using remoteview. Problem I'm facing is, How to autoCancel the notification once the user touches it.
I did try few things, but none is giving desired result.
Find Code below:
RemoteViews remoteView = new RemoteViews(this.getPackageName(), R.layout.notification_layout);
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
builder.setSmallIcon(R.drawable.ic_launcher);
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this, RQST_CODE, intent, PendingIntent.FLAG_CANCEL_CURRENT);
remoteView.setOnClickPendingIntent(R.id.btnNotification, pIntent);
builder.setAutoCancel(true);
builder.setContent(remoteView);
Notification notify = builder.build();
notify.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(NOTY_ID, notify);
For others who have a custom layout and want auto cancel to work,
If clicking anywhere on notification is ok, then don't use remoteView.setOnClickPendingIntent. Because any view with OnClick Listener overrides the notification main OnClick Listener.
Use setContentIntent instead:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle("title");
builder.setContentText("contect");
builder.setSmallIcon(#smallicon);
builder.setWhen(#when);
builder.setContent(remoteViews);
builder.setContentIntent(onClickPendingIntent); // use this
builder.setAutoCancel(true);
The way I achieved this is by creating BroadcastReceiver which controls button clicks from Notification. Create something like this :
public class NotificationButtonListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int action = intent.getIntExtra("mode", -1);
switch (action) {
// do some things depending on action if there are more stuff to do
}
}
}
Don't forget to add your BroadcastListener to your manifest file:
<receiver android:name=".NotificationButtonListener">
And you can create a helper class for creating and cancelling notification:
public class NotificationHelper {
private static final int NOTIFICATION_ID = 5;
private static NotificationManager mNotificationManager = null;
public static void showNotification(Context context) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
contentView.setOnClickPendingIntent(R.id.btn_close, closePendingIntent);
Intent mMainIntent = new Intent(context, MainActivity.class);
mMainIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent mMainPendingIntent = PendingIntent.getActivity(context, 555, mMainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setTicker("Playing")
.setContent(contentView)
.setAutoCancel(false)
.setOngoing(true)
.setSmallIcon(R.drawable.ic_av_play)
.setContentIntent(mMainPendingIntent);
Notification notification = mBuilder.build();
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
public static void cancelNotification() {
if (mNotificationManager != null) {
mNotificationManager.cancelAll();
}
}
}
And using that class in your NotificationButtonListener you can call NotificationHelper.cancelNotification(); .
Hope this helps you!
Related
i see many post on stackoverflow but i can't find a fix to my problem.
I have a notification with a custom content view with a button linked with a RemoteViews. I followed this link (Adding button action in custom notification) for attach an action to my button, but my BroadcastReceiver is never fired. The code:
private void createNotification(int index){
final int id = index;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification);
contentView.setInt(R.id.container,"setBackgroundColor",ContextCompat.getColor(this,BG_COLORS[index]));
contentView.setImageViewResource(R.id.logo,BUTTON_OFF[index]);
contentView.setTextViewText(R.id.sound, getString(SOUND_NAME[index]) );
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContent(contentView);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, id, notificationIntent, 0);
Notification notification = mBuilder.build();
notification.contentIntent = contentIntent;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent closeButton = new Intent(this,StopReceiver.class);
closeButton.setAction(StopReceiver);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, closeButton,0);
contentView.setOnClickPendingIntent(R.id.stop,pendingIntent);
mNotificationManager.notify(id, notification);
}
public static class StopReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Never called
Log.d(LOGTAG,"Received Cancelled Event");
...
}
}
I have also declared my receiver in my AndroidManifest.xml:
<receiver android:name="StopReceiver" android:enabled="true" />
Thank you.
You are setting the setOnClickPendingIntent of the RemoteViews after supplying it as the custom RemoteView of the Notification.
Try setting setOnClickPendingIntent before calling setContent. E.g.:
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification);
contentView.setInt(R.id.container,"setBackgroundColor",ContextCompat.getColor(this,BG_COLORS[index]));
contentView.setImageViewResource(R.id.logo,BUTTON_OFF[index]);
contentView.setTextViewText(R.id.sound, getString(SOUND_NAME[index]) );
Intent closeButton = new Intent(this,StopReceiver.class);
closeButton.setAction(StopReceiver);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, closeButton,0);
contentView.setOnClickPendingIntent(R.id.stop,pendingIntent);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContent(contentView);
If you are using listview in widget then it is very costly to set PendingIntents on the individual items, and is hence not permitted. Instead a single PendingIntent template can be set on the collection, you can use setOnClickFillInIntent()
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_article_list_item);
Intent intent = new Intent(context, ArticleDetailActivity.class); //activity to start
intent.putExtra("article",articleList.get(position));//any data to send
//don't use pending intent here
views.setOnClickFillInIntent(R.id.widget_item, intent);
You can use this in overridden method getViewAt(final int position) { ... }
I have the following code to make a notification when the network state changes.
but when i change the network state the app stops working !
please help me with making notification.
I am sure the problem is in addMyNotification function . but dont know how to fix it.
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent broadcast) {
addMyNotification("hi","hello",1,context);
}
private void addMyNotification(String title,String message,int id ,Context context ) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true);
Intent notificationIntent = new Intent(context, SendFood.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, id, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
manager.notify(id, builder.build());
}
I am new to android and currently learning about notifications, there's a small app I am making which is supposed to show notification later in time and should open an activity when user taps on them. I have been looking for content all over internet but can't really understand how to do both task. I am using a broadcast receiver and here's my code
Notification.Builder builder = new Notification.Builder(getActivity());
builder.setContentTitle("Remember to return");
builder.setContentText(title);
builder.setSmallIcon(R.drawable.ic_notification);
builder.setAutoCancel(true);
//NotificationCompat.Builder builder = new NotificationCompat.Builder(getActivity());
Notification notification = builder.build();
Intent notificationIntent = new Intent(getActivity(),NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID,1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION,notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(activity,0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//long _notificationTimeInMillis = SystemClock.elapsedRealtime()+date.getTime()+getMillisFromHours(6);
long notificationTimeInMillis = SystemClock.elapsedRealtime() + 5000;
AlarmManager alarmManager = (AlarmManager)activity.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,notificationTimeInMillis,pendingIntent);
Toast.makeText(activity,"Notification Set",Toast.LENGTH_SHORT);
and for reciever
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
Currently I am able to show notifications, what changes to I have to make so that an activity (say HomeActivity.class) opens when user clicks on notification.
You need to set a pending intent on the notification itself that will open the activity:
Notification.Builder builder = new Notification.Builder(getActivity());
builder.setContentTitle("Remember to return");
builder.setContentText(title);
builder.setSmallIcon(R.drawable.ic_notification);
builder.setAutoCancel(true);
// add these lines
PendingIntent pi = PendingIntent.getActivity(
getActivity(),
REQUEST_CODE_FOR_THIS_ONE,
new Intent(getActivity(), HomeActivity.class),
0
);
builder.setContentIntent(pi);
Notification notification = builder.build();
Can i remove this notification in a click on notication?
I can cancel notification when click on this notification using the setAutoCancel(true).
but not clear notification after click on notification.
private void sendNotification(String msg, Bundle extras) {
notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent;
if (extras != null) {
intent = new Intent(this, MessageConversationActivity.class);
intent.putExtra("sender_id", extras.get("sender_id").toString());
intent.putExtra("receiver_id", Application.ACTIVE_USER.getUser_id());
intent.putExtra("gender", extras.get("gender").toString());
intent.putExtra("profile_picture", extras.get("profile_picture")
.toString());
intent.putExtra("username", extras.get("username").toString());
} else {
intent = new Intent(this, MainActivity.class);
}
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, 0);
String app_name = getString(R.string.app_name);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.app_icon)
.setContentTitle(app_name)
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
builder.setContentIntent(contentIntent);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
Try This
builder.setAutoCancel(true);
If you set your notification to auto-cancel it is also removed once the user selects it.
OR
You can also call the cancel() for a particular notification ID to cancel notification.
notificationManager.cancel(notifyId);
Use this in the MessageConversationActivity class onCreate method.
Use notificationManager.cancel(NOTIFICATION_ID);
It cancel the notification id from the notification manager
you can do this by using
Notification.FLAG_AUTO_CANCEL
then start intent of page you want
My app plays music and when users open notifications screen by swiping from the top of the screen ( or generally from the bottom right of the screen on tablets ), I want to present them a button to stop the currently playing music and start it again if they want.
I am not planning to put a widget on the user's home screen, but just into notifications. How can I do this?
You can create an intent for the action (in this case stop playing) and then add it as an action button to your notification.
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
snoozePendingIntent);
Please refer to the Android documentation.
I will try to provide a solution that I have used and most of the music player also use the same technique to show player controls in notification bar.
I am running a service which is used to manage Media Player and all its controls. Activity User control interacts with Service by sending Intents to the service for example
Intent i = new Intent(MainActivity.this, MyRadioService.class);
i.setAction(Constants.Player.ACTION_PAUSE);
startService(i);
TO receive intents and perform action in Service class I am using following code in onStartCommand method of Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.Player.ACTION_PAUSE)) {
if(mediaPlayer.isPlaying()) {
pauseAudio();
}
}
Now to exact answer to your question to show notification with playing controls. You can call following methods to show notification with controls.
// showNotification
private void startAppInForeground() {
// Start Service in Foreground
// Using RemoteViews to bind custom layouts into Notification
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.notification_status_bar);
// Define play control intent
Intent playIntent = new Intent(this, MyRadioService.class);
playIntent.setAction(Constants.Player.ACTION_PLAY);
// Use the above play intent to set into PendingIntent
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
playIntent, 0);
// binding play button from layout to pending play intent defined above
views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
views.setImageViewResource(R.id.status_bar_play,
R.drawable.status_bg);
Notification status = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
status = new Notification.Builder(this).build();
}
status.flags = Notification.FLAG_ONGOING_EVENT;
status.icon = R.mipmap.ic_launcher;
status.contentIntent = pendingIntent;
startForeground(Constants.FOREGROUND_SERVICE, status);
}
Hope this really helps you. And you will be able to achieve what you want. Have a Happy Coding :)
// It shows buttons on lock screen (notification).
Notification notification = new Notification.Builder(context)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.NotIcon)
.addAction(R.drawable.ic_prev, "button1",ButtonOneScreen)
.addAction(R.drawable.ic_pause, "button2", ButtonTwoScreen)
.....
.setStyle(new Notification.MediaStyle()
.setShowActionsInCompactView(1)
.setMediaSession(mMediaSession.getSessionToken())
.setContentTitle("your choice")
.setContentText("Again your choice")
.setLargeIcon(buttonIcon)
.build();
Please refer this for more details Click here
tested, working code with android Pie. These all go inside the same service class.
Show a notification:
public void setNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = new NotificationChannel("a", "status", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("notifications");
notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
else
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Receiver.service = this;
Notification.MediaStyle style = new Notification.MediaStyle();
notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Notification")
.addAction(R.drawable.close_icon, "quit_action", makePendingIntent("quit_action"))
.setStyle(style);
style.setShowActionsInCompactView(0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
notification.setChannelId("a");
}
// notificationManager.notify(123 , notification.build()); // pre-oreo
startForeground(126, notification.getNotification());
}
Helper function:
public PendingIntent makePendingIntent(String name)
{
Intent intent = new Intent(this, FloatingViewService.Receiver.class);
intent.setAction(name);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
return pendingIntent;
}
To handle the actions:
static public class Receiver extends BroadcastReceiver {
static FloatingViewService service;
#Override
public void onReceive(Context context, Intent intent)
{
String whichAction = intent.getAction();
switch (whichAction)
{
case "quit_action":
service.stopForeground(true);
service.stopSelf();
return;
}
}
}
You'll need to update your manifest too:
<receiver android:name=".FloatingViewService$Receiver">
<intent-filter>
<action android:name="quit_action" />
</intent-filter>
</receiver>
I think that beside Ankit Gupta answer, you can use MediaSession (API > 21) to add native mediaController view :
notificationBuilder
.setStyle(new Notification.MediaStyle()
.setShowActionsInCompactView(new int[]{playPauseButtonPosition}) // show only play/pause in compact view
.setMediaSession(mSessionToken))
.setColor(mNotificationColor)
.setSmallIcon(R.drawable.ic_notification)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setUsesChronometer(true)
.setContentIntent(createContentIntent(description)) // Create an intent that would open the UI when user clicks the notification
.setContentTitle(description.getTitle())
.setContentText(description.getSubtitle())
.setLargeIcon(art);
Source: tutorial
you can alse create custom view and display it in the notificcation area , first answer here is great.
you can add button as below and can perform action on that button also i have done for me as below please check.
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_logo)
.setAutoCancel(true)
.setContentTitle(name)
.setContentText(body)
.setGroupSummary(true)
.addAction(android.R.drawable.ic_menu_directions, "Mark as read", morePendingIntent);
//morePendingIntent(do your stuff)
PendingIntent morePendingIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE_MORE,
new Intent(this, NotificationReceiver.class)
.putExtra(KEY_INTENT_MORE, REQUEST_CODE_MORE)
.putExtra("bundle", object.toString()),
PendingIntent.FLAG_UPDATE_CURRENT
);
I don't know if this is the right way or not, but it works.
Create a BroadCastReceiver class to receive the data when button is pressed.
public class MyBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String log = "URI: " + intent.toUri(Intent.URI_INTENT_SCHEME);
Log.d("my", "LOG:::::::" + log);
}
}
Now in any activity where you want to create the notification -
Intent intent = new Intent();
intent.setAction("unique_id");
intent.putExtra("key", "any data you want to send when button is pressed");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, 0);
Now use this pending intent when you are creating the notification and lastly you need to register this broadcast in order to receive it in MyBroadCastReceiver class.
BroadcastReceiver br = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter("unique_id");
registerReceiver(br, filter);
Now if you want to do certain things when the button is pressed, you can do so in the onReceive() method in MyBroadCastReceiver class.