I am trying to send a broadcast when a pause button on a notification is clicked. The notification is fired from a background service that controls a music player.
This is the notification.
private void showPlayerNotification() {
Intent notifyIntent = new Intent(this, PlayerActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(Constants.RADIO_SERVICE_ACTION_RECEIVER);
pauseIntent.putExtra(Constants.RADIO_SERVICE_ACTION, RadioService.PAUSE_ACTION);
PendingIntent pausePendingIntent = PendingIntent.getBroadcast(this, 1, pauseIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentIntent(pendingIntent)
.setStyle(new MediaStyle().setShowActionsInCompactView(0))
.setSmallIcon(R.drawable.play)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.setColorized(true)
.setColor(getResources().getColor(R.color.player_background))
.setAutoCancel(true)
.setContentTitle(mediaStream.getStreamName())
.addAction(R.drawable.notification_pause, "Pause", pausePendingIntent);
Notification mediaNotification = notificationBuilder.build();
startForeground(1, mediaNotification);
}
The broadcast receiver is defined in the Service and is registered with an intent filter Constants.RADIO_SERVICE_ACTION_RECEIVER. I use the same broadcast receiver successfully to control playback where the broadcast originate from an activity.
The above pauseIntent broadcast is not getting through to the broadcast receiver. Could it be that the service context causing the issue?
I have successfully received the intent in my player activity by using a PendingIntent.getActivity but I don't want to handle it in the activity as that might mess the activity code.
Related
I have a Flutter app, which runs a never ending foreground service and it is defined like this:
private void startForeground() {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
startForeground(NOTIF_ID, new NotificationCompat.Builder(this,
NOTIF_CHANNEL_ID)
.setOngoing(true)
.setContentTitle("service")
.setContentText("Service is running background")
.setContentIntent(pendingIntent)
.build());
}
and I start service like this:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.smile)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
My foreground service is showing notification all the time.
Is it possible to start a Flutter app when user press on notification which is showed by foreground service, even if the Flutter app isn't running in background? Thanks.
To launch an Activity when clicking on a notification, you can use the PendingIntent. You already have this implemented in the first sample, but here are some links. Android docs Stackoverflow question
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
builder.setContentIntent(pendingIntent);
I am trying to implement multiple notifications for each reminder I have in my app. I found some leads around here that it could be achieved using unique id per each notification but it is not working I get only one notification which is overwritten by the last one set. Also I would like know how is it possible to keep the notification intact after device is rebooted please. Here is my code
//call notification activation Intent
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
AlarmReceiver class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//creating unique id for each specific notification
int ID = (int) ((new Date().getTime()/1000L) % Integer.MAX_VALUE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notification = new Intent(context,MainActivity.class);
notification.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(context,0,notification,0);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mynotification = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_date_range_black_48dp)
.setContentTitle("note taker")
.setContentText("you have a reminder about a note")
.setAutoCancel(true)
.setContentIntent(pi)
.setSound(defaultSoundUri)
.setVibrate(new long[]{1000,1000,1000,1000,1000});
notificationManager.notify(ID,mynotification.build());
}
}
I found some leads around here that it could be achieved using unique id per each notification but it is not working i get only one notification which is overwritten by the last one set
I think the problem lies not in your notification, but in your AlarmManager.
Try using different ID for each PendingIntent, and set the flag to PendingIntent.FLAG_ONE_SHOT.
Your calling intent should look like this:
//call notification activation Intent
Intent intent = new Intent(getBaseContext(), AlarmReciever.class);
int RQS_1 = (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Try to give different request code and PendingIntent.FLAG_UPDATE_CURRENT as Flag for Pending Intent and check like this,
PendingIntent pi = PendingIntent.getActivity(context, new Random().nextInt(1000000), notification, PendingIntent.FLAG_UPDATE_CURRENT);
I am developing an app with alarmmanager and services and I cannot cancel the notification in certain cases. I am using fragments.
My app send two notifications every "x" different minutes. I have a button to start the service and another one to stop it. When I start the service the notifications are fired and when I press the stop button it works correctly. But when I start the service and I exit the app, the notifications are fired normally but when I click a notification, the app is opened and then I press the stop button but the notifications never stop, the notifications continue being fired.
The function where I call alarmanager.cancel(pendingintent) is in the same fragment.. (MainFragment.class which is the first fragment).
MainFragment.class
intent = new Intent(getContext(), TimeAlarm.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
intent.setAction(Long.toString(System.currentTimeMillis()));
pendingIntent = PendingIntent.getBroadcast(mContext, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 15000,
15000,
pendingIntent);
intent2 = new Intent(getContext(), TimeAlarm2.class);
intent2.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
intent2.setAction(Long.toString(System.currentTimeMillis()));
pendingIntent2 = PendingIntent.getBroadcast(getContext(), 1,
intent2, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 15000,
15000,
pendingIntent2);
TimeAlarm.class which extends BroadcastReceiver
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.icon)
.setContentTitle("...")
.setContentText("...");
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setAutoCancel(true);
mBuilder.build().flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
TimeAlarm2.class which extends BroadcastReceiver
NotificationCompat.Builder mBuilder2 = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.icon2)
.setContentTitle("..")
.setContentText("..");
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder2.setContentIntent(resultPendingIntent);
mBuilder2.setAutoCancel(true);
mBuilder2.build().flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder2.build());
Thanks and best regards!
Remove these lines from both intent and try it again.
intent2.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
intent2.setAction(Long.toString(System.currentTimeMillis()));
It is working for me
Try this and if the error comes telling me what happens.
For that you need to destroy the service on the stop button and again start service on start button click.
Okay. I can suggest you to call cancel() on AlarmManager with an equivalent PendingIntent to the one you used with setRepeating() method.
Here you can cancel both of your equivalent pendingIntent.
am.cancel(pendingIntent);
and
am.cancel(pendingIntent2);
Hope it will help you.
I have implemented some notifications in my application. It seems that everytime I click on the notification it starts a new intent. The goal is to bring the application in the foreground because it is still in background (so not killed).
How can I achieve this?
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, ChatActivity.class), 0);
long[] vibration = new long[]{100, 250};
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setTicker(msg)
.setLights(Color.WHITE, 300, 600)
.setSound(Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" + R.raw.new_msg))
.setVibrate(vibration)
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
To bring the application to the front, use the following intent in the Pending Intent.
Intent intent = new Intent(this, ChatActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
This'll resume the application if not already killed or open the ChatActivity if it has been killed.
I have successfully created a notification thanks to my other question, using NotificationCompat. I want to now just change what the notification does onClick. I'd really just like to have an alert dialog pop up (I've seen some app's do it) but everytime I click it, I just have my activity show up. Any ideas?
The notification code:
Intent notificationIntent = new Intent(ctx, YourClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(ctx,
YOUR_PI_REQ_CODE, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager nm = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = ctx.getResources();
Notification.Builder builder = new Notification.Builder(ctx);
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.some_img)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.some_big_img))
.setTicker(res.getString(R.string.your_ticker))
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentTitle(res.getString(R.string.your_notif_title))
.setContentText(res.getString(R.string.your_notif_text));
Notification n = builder.build();
nm.notify(YOUR_NOTIF_ID, n);
You can't have a normal dialog without an activity. There are several possible workarounds though including styling the activity like a dialog and making the activity itself invisible and launching a dialog from it immediately.
You can probably use Remote Views to show a dialog without going to your app process.
you can set
Intent intent = new Intent(context, ReserveStatusActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
intent = new Intent(String.valueOf(PushActivity.class));
intent.putExtra("message", MESSAGE);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(PushActivity.class);
stackBuilder.addNextIntent(intent);
// PendingIntent pendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.BigPictureStyle notiStyle = new
NotificationCompat.BigPictureStyle();
android.app.Notification notification = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(en_title)
.setContentText(en_alert)
.setAutoCancel(true)
.setNumber(++numMessages)
.setStyle(notiStyle)
//.setContentIntent(resultPendingIntent)
.setContentIntent(pendingIntent)
.build();
notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationManager.notify(1000, notification);