On my radio streaming app i want to stop the player from playing.
How to add a button in the notification to stop or kill the player?
I have this so far:
private void initNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(StreamService.this, 0, new Intent(this, Radio.class), 0);
builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_ricky)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
.setContentTitle("Radio")
builder.setContentIntent(intent);
builder.setOngoing(true);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
Add a close button to the notification layout. Create some intent like this:
final ComponentName srvComp = new ComponentName(getContext(), service.getClass());
Intent close = new Intent(YourRadioService.ACTION_PLAYER_CLOSE);
close.setComponent(srvComp);
mPiClose = PendingIntent.getService(getContext(), 4, close, PendingIntent.FLAG_UPDATE_CURRENT);
Inflate your RemoteView somehow, for example:
RemoteViews smallNotification = new RemoteViews(getContext().getPackageName(), R.layout.notification_small);
smallNotification.setOnClickPendingIntent(R.id.close, mPiClose);
Set the content view on the notification
notification.contentView = smallNotification;
After that, use the notification manager to provide the notification
notificationManager.notify(NOTIFICATION_ID, notification);
Don't forget to handle the Intent. If you need more help look up how some open source music players are doing it.
Related
I'm not sure what I'm doing wrong, the notification is the way I like it but I cannot get it to make the watch vibrate, and it shows as minimized. the effect I want to achieve should look like hangouts notification, which vibrate and go fullscreen. here is the code I'm using (on the watch):
Intent actionIntent = new Intent(this, ConvActivity.class);
actionIntent.putExtra("num",num);
PendingIntent actionPendingIntent =
PendingIntent.getActivity(this, 0, actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Create the action
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(R.drawable.ic_launcher,"Reply"
, actionPendingIntent)
.build();
NotificationCompat.BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
bigStyle.bigText(body).setBigContentTitle(name);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(name)
.setContentText(body)
//.setContentIntent(viewPendingIntent)
//.addAction(R.drawable.ic_map,
// getString(R.string.map), mapPendingIntent)
.setStyle(bigStyle).setAutoCancel(true)
.addAction(R.drawable.ic_launcher,"Reply"
, actionPendingIntent);
if(pic != null)
notificationBuilder.setLargeIcon(BitmapFactory.decodeByteArray(pic,0,pic.length));
//.extend(new NotificationCompat.WearableExtender().addAction(action)) ;
// Get an instance of the NotificationManager service
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(this);
// Issue the notification with notification manager.
notificationManager.notify(0, notificationBuilder.build());
Only notifications that vibrate/sound will vibrate an Android Wear device and show more text.
You should consider using the NotificationCompat.Builder.setDefaults() method:
// Light, sound, and vibrate
builder.setDefaults(Notification.DEFAULT_ALL);
// Just sound
builder.setDefaults(Notification.DEFAULT_SOUND);
// Just vibrate
builder.setDefaults(Notification.DEFAULT_VIBRATE);
This is the code that gives notification on start of service
NotificationCompat.Builder mbuild = new NotificationCompat.Builder(getApplicationContext());
Intent in = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent resultIN = PendingIntent.getActivity(getApplicationContext(),code,in,NOTIFICATION_COUNT); mbuild.setSmallIcon(R.drawable.images1);
mbuild.setContentText(NOTIFICATION_COUNT +" New Message");
mbuild.setContentIntent(resultIN); //mbuild.addAction(R.drawable.notifications,NOTIFICATION_COUNT +"New Messages",resultIN);
NotificationManager nmagr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nmagr.notify(1, mbuild.build());
everyting is working correct ..the code opens the target activity but the notification still stays there in the notification bar.
i have tried useing mbuil.setautocancel(true); but its doing nothing
try this
NotificationManager nmagr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification=mbuild.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
nmagr.notify(1,notification);
You didn't set setAutoCancel(true)
Just set this
mbuild.setAutoCancel(true)
or
mbuild.getNotification().flags |= Notification.FLAG_AUTO_CANCEL
Updated
You can also try below code.
NotificationManager mgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
mgr.cancel(1); // here is "1" is your notification id which you set at "nmagr.notify(1, mbuild.build());"
write above code in your onCreate() method of MainActivity.class.
NotificationManager notification_manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notification_manager.cancel(NOTIFICATION_ID);
Just an update to anyone doing this with NotificationCompat and / or using the Notificaitoncompat.Builder.
This is how I did mine :
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle(title);
/* your own code here */
builder.setAutoCancel(true);
Notification notification = builder.build();
NotificationManagerCompat.from(this).notify(0,notification);
It is important to note that if you use a pending intent to redirect the user to a specific intent in your app, this will also call the pending intent.
As per the documentation :
Setting this flag will make it so the notification is automatically canceled when the user clicks it in the panel. The PendingIntent set with setDeleteIntent will be broadcast when the notification is canceled.
I have a notification that have 2 actions. One intent open an Activity, the other open browser web.
my code:
Intent intent1 = new Intent(context, NotificationClickActivity.class);
PendingIntent pIntent1 = PendingIntent.getActivity(context, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
String url = "http://www.google.com";
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
browserIntent.setData(Uri.parse(url));
PendingIntent pBrowserIntent = PendingIntent.getActivity(context, 1, browserIntent, PendingIntent.FLAG_CANCEL_CURRENT);
// Build notification
Notification noti = new Notification.Builder(context)
.setContentTitle(title)
.setContentText(shortDescription)
.setStyle(new Notification.BigTextStyle().bigText(longDescription))
.setSmallIcon(R.drawable.small_defaulticon)
.setAutoCancel(true)
.setContentIntent(pIntent1)
.addAction(R.drawable.playstore_icon_32, "Dettagli", pIntent1)
.setContentIntent(pBrowserIntent)
.addAction(R.drawable.small_defaulticon, "Vai al sito", pBrowserIntent).build();
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
If i click on the notification it goes away, but if I click on one of the 2 Actions it open the right intent but notification doesn't cleared.
I try also .setDeleteIntent(myPendingIntent) but nothing... I wonder where I am going wrong...
A screen of my notification...
Thank you!
A notification is never dismissed when an action button is pressed. It just sends you associated intent. If you want it to dismiss, you need to call NoficationManager.cancel(int id) to cancel it yourself. You will normally do it in the same method, which handles action button intent.
Notification.FLAG_AUTO_CANCEL flag you tried to use is only applied to notification body and not to action buttons.
use cancel() in the activity that started by your action to dismiss the notification
try this
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setDefaults(Notification.DEFAULT_ALL);
and try to send uniqueId in notificationManager.notify(uniqueId, noti);
I want to add a tap action (exit (finish)) to a notification.
I'm making a simple app with several classes, and I want them all finished when I tap the notification.
Here is my notification code:
mMN = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification n = new Notification();
n.icon = R.drawable.ic_launcher;
n.tickerText = "Tap this notification to exit";
n.when = System.currentTimeMillis();
Intent nid = new Intent(MainActivity.this, stopservice.class);
PendingIntent ci = PendingIntent.getActivity(this, 0, nid,PendingIntent.FLAG_UPDATE_CURRENT);
CharSequence ct = "TAP";
CharSequence tt = "Tap here to exit";
n.setLatestEventInfo(this,ct,tt,ci);
mMN.notify(NOTIFICATION_ID, n);
I'm making a reference to stopservice class (where it is my stop service code) on Intent nid, but I'm not quite sure if it's a correct reference.
hope that my question is clear.
You should be using a notification builder:
mMN = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent nid = new Intent(MainActivity.this, stopservice.class);
// If you were starting a service, you wouldn't using getActivity() here
PendingIntent ci = PendingIntent.getActivity(MainActivity.this, NOTIFICATION_ID, nid, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(MainActivity.this);
builder.setContentTitle("TAP")
.setContentText("Tap here to exit")
.setTicker("Tap this notification to exit")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(ci)
.setAutoCancel(true); // auto cancel means the notification will remove itself when pressed
mMN.notify(NOTIFICATION_ID, builder.getNotification());
Your code is set to launch the Activity "stopservice" (which technically should be "StopService" with naming conventions), are you sure that class is an Activity?
Also, make sure your Activity is registered in your app's manifest:
<activity android:name="[package-name].stopservice" android:label="#string/app_name"/>
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.