I have implemented android notifications in android studio. I was creating notification for a media player. following is the function for showing notifications
public void showNotification(int playPauseBtn)
{
Intent intent = new Intent(this, PlayerActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Intent prevIntent = new Intent(this, NotificationReceiver.class).setAction(ACTION_PREVIOUS);
PendingIntent prevPending = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(this, NotificationReceiver.class).setAction(ACTION_PLAY);
PendingIntent pausePending = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent nextIntent = new Intent(this, NotificationReceiver.class).setAction(ACTION_NEXT);
PendingIntent nextPending = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
byte[] picture = null;
try
{
picture = getAlbumArt(listSongs.get(position).getPath());
} catch (Exception ignored)
{
}
Bitmap thumb;
if (picture != null)
{
thumb = BitmapFactory.decodeByteArray(picture, 0, picture.length);
} else
{
thumb = BitmapFactory.decodeResource(getResources(), R.drawable.icon_music);
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID_1).setSmallIcon(playPauseBtn)
.setLargeIcon(thumb)
.setContentTitle(listSongs.get(position).getTitle())
.setContentText(listSongs.get(position).getArtist())
.addAction(R.drawable.ic_baseline_skip_previous_24, "Previous", prevPending)
.addAction(R.drawable.ic_baseline_skip_next_24, "Next", nextPending)
.addAction(playPauseBtn, "pause", pausePending)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle().setMediaSession(mediaSessionCompat.getSessionToken()))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setOnlyAlertOnce(true)
.setContentIntent(contentIntent)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
Toast.makeText(PlayerActivity.this, "Nitification created", Toast.LENGTH_SHORT).show();
}
In the function parameter (playPauseBtn) I am sending the play icon or the pause icon depending upon weather the song is playing or is paused.
Function call is made like following:
showNotification(R.drawable.ic_baseline_pause_24);
OR
showNotification(R.drawable.ic_baseline_play_arrow_24);
But when ever I call this function the notification doesn't show up. I am also using the notification channel but still it is not working. I have also tried to debug the code but the code runs fine, still the notification doesn't show up. please advise
try this.
put this code in your Activity/fragment;
public void getNotification(){
int notifId =new Random().nextInt(500); //get random id
NotificationManager notificationManager;
Notification notification;
notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channelID = "1";
channelName = "news";
channelDesc = "news description";
NotificationChannel notificationChannel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setDescription(channelDesc);
notificationChannel.enableLights(true);
notificationChannel.setSound(null, null);
notificationChannel.setLightColor(Color.GREEN);
notificationManager.createNotificationChannel(notificationChannel);
}
RingtoneManager.getRingtone(mContext,
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)).play();
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, channelID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("title Of MUSIC")
.setContentText("Content")
.setVibrate(new long[]{100, 500, 500, 500, 500})
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
Intent actionReadMessage = new Intent(mContext, NotifAction.class);
actionReadMessage.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
actionReadMessage.setAction("Play");
actionReadMessage.putExtra("NotifId",notifId);
PendingIntent playPendingIntent = PendingIntent.getBroadcast(mContext, notifId, actionReadMessage,PendingIntent.FLAG_CANCEL_CURRENT);
Intent mainAction = new Intent(mContext, NotifAction.class);
mainAction.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mainAction.setAction("Pause");
mainAction.putExtra("NotifId",notifId);
PendingIntent PausePendingIntent = PendingIntent.getBroadcast(mContext, notifId, mainAction,PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentIntent(PausePendingIntent);
builder.addAction(R.mipmap.ic_launcher, "Play", playPendingIntent);
builder.addAction(R.mipmap.ic_launcher, "Pause", PausePendingIntent);
notification = builder.build();
notificationManager.notify(notifId, notification);
}
and create class NotifAction.class for handle all action:
public class NotifAction extends BroadcastReceiver {
private static final String TAG = "maybe";
private MediaPlayer mp;
#Override
public void onReceive(final Context context, Intent intent) {
String action = intent.getAction();
Bundle extra = intent.getExtras();
if (extra != null) {
int notifId = extra.getInt("NotifId");
if (action.equals("Play")) {
mp = MediaPlayer.create(context, R.raw.music);
handleMusicState(mp);
} else if (action.equals("Pause")) {
handleMusicState(mp);
setMessageRead(notifId, context);
} else {
Toast.makeText(context, "extra action !", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "Empty extra !", Toast.LENGTH_SHORT).show();
}
}
private void setMessageRead(int id, Context context) {
// other method
clearNotification(id, context);
}
private void clearNotification(int id, Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
private void handleMusicState(MediaPlayer mediaPlayer) {
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
else mediaPlayer.start();
}
}
define this receiver to manifest:
note:in tag
<receiver android:name=".NotifAction">
<intent-filter>
<action android:name="Play" />
<action android:name="Pause" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
FIX
Donot use .setMediaSession(mediaSessionCompat.getSessionToken()) in .setStyle() in the code given in the question
simply just use
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle())
Related
I have a notification in my music app with following code:
void showNotification(int playPauseBtn){
Intent intent = new Intent(this, PlayerActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Intent prevIntent = new Intent(this, NotificationReceiver.class)
.setAction(ACTION_PREVIOUS);
PendingIntent prevPending = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(this, NotificationReceiver.class)
.setAction(ACTION_PLAY);
PendingIntent pausePending = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent nextIntent = new Intent(this, NotificationReceiver.class)
.setAction(ACTION_NEXT);
PendingIntent nextPending = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
byte[] picture = null;
picture = getAlbumArt(musicFiles.get(position).getPath());
Bitmap thumb = null;
if (picture != null){
thumb = BitmapFactory.decodeByteArray(picture, 0, picture.length);
}
else{
thumb = BitmapFactory.decodeResource(getResources(), R.drawable.musicicon);
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID_2)
.setSmallIcon(playPauseBtn)
.setLargeIcon(thumb)
.setContentTitle(musicFiles.get(position).getTitle())
.setContentText(musicFiles.get(position).getArtist())
.addAction(R.drawable.ic_skip_previous, "Previous", prevPending)
.addAction(playPauseBtn, "Pause", pausePending)
.addAction(R.drawable.ic_skip_next, "Next", nextPending)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSessionCompat.getSessionToken()))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setOnlyAlertOnce(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.build();
startForeground(2, notification);
notificationManager =
(NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(2, notification);
}
I have created separate class(ApplicationClass) for creating notification channel.
#Override
public void onCreate() {
super.onCreate();
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel channel1 =
new NotificationChannel(CHANNEL_ID_1,
"Channel(1)", NotificationManager.IMPORTANCE_HIGH);
channel1.setDescription("Channel 1 Desc..");
NotificationChannel channel2 =
new NotificationChannel(CHANNEL_ID_2,
"Channel(2)", NotificationManager.IMPORTANCE_HIGH);
channel1.setDescription("Channel 2 Desc..");
//HERE ABOVE DOUBT
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel1);
notificationManager.createNotificationChannel(channel2);
}
}
}
And also, I have a class (NotificationReceiver) for receiving notification action:
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String actionName = intent.getAction();
Intent serviceIntent = new Intent(context, MusicService.class);
if (actionName != null){
switch (actionName){
case ACTION_PLAY:
serviceIntent.putExtra("ActionName", "playPause");
context.startService(serviceIntent);
break;
case ACTION_NEXT:
serviceIntent.putExtra("ActionName", "next");
context.startService(serviceIntent);
break;
case ACTION_PREVIOUS:
serviceIntent.putExtra("ActionName", "previous");
context.startService(serviceIntent);
break;
}
}
}
}
My notification functions(play, pause & next) works properly, but my problem is that, I am unable to clear notification. I tried many times but I could not get it right.
try this
void showNotification(int playPauseBtn){
Intent intent = new Intent(this, NotifAction.class);
//add this to get IdNotif.for all intent
intent.putextra("NotifId",notifId);
//
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Intent prevIntent = new Intent(this, NotifAction.class)
.setAction(ACTION_PREVIOUS);
PendingIntent prevPending = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(this, NotifAction.class)
.setAction(ACTION_PLAY);
PendingIntent pausePending = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent nextIntent = new Intent(this, NotifAction.class)
.setAction(ACTION_NEXT);
PendingIntent nextPending = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
byte[] picture = null;
picture = getAlbumArt(musicFiles.get(position).getPath());
Bitmap thumb = null;
if (picture != null){
thumb = BitmapFactory.decodeByteArray(picture, 0, picture.length);
}
else{
thumb = BitmapFactory.decodeResource(getResources(), R.drawable.musicicon);
}
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID_2)
.setSmallIcon(playPauseBtn)
.setLargeIcon(thumb)
.setContentTitle(musicFiles.get(position).getTitle())
.setContentText(musicFiles.get(position).getArtist())
.addAction(R.drawable.ic_skip_previous, "Previous", prevPending)
.addAction(playPauseBtn, "Pause", pausePending)
.addAction(R.drawable.ic_skip_next, "Next", nextPending)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSessionCompat.getSessionToken()))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setOnlyAlertOnce(true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.build();
startForeground(notifId, notification);
notificationManager =
(NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(notifId, notification);
}
set notifId for eachNotification and make this class for handle all action in notification.
note :
To set each event for each notification button, you first rationalize all actions to the NotifAction class, and from there define click events for each using the class.
create class for HandleAction:
public class NotifAction extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
String action = intent.getAction();
Bundle extra = intent.getExtras();
if (extra != null) {
if (action.equals("YourActionName")) {
clearNotification(extra.getInt("YourNotifId",0),context);
Toast.makeText(context, "YourMessage!", Toast.LENGTH_SHORT).show();
} else
/// another event for each action
}
private void clearNotification(int id, Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
}
I have an app that sends/receives notification using Firebase. Im sending the notification with no problem, but if the app is open the notification display an square instead of the smallicon also if i click the notification nothing happens, but if i'm using a different app i receive the notification and the notification show the correct icon and also opens the app.
public class MyMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
public void showNotification(String title, String message) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "MyNotifitcation")
.setContentTitle(title)
.setSmallIcon(R.drawable.ic_launcher_background)
.setAutoCancel(true)
.setContentText(message);
NotificationManagerCompat manager = NotificationManagerCompat.from(this);
manager.notify(999, builder.build());
}
}
public class MainActivity extends AppCompatActivity {
private String TAG = MainActivity.class.getSimpleName();
String title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel =
new NotificationChannel("MyNotifitcation", "MyNotifitcation", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
FirebaseMessaging.getInstance().subscribeToTopic("general").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
String msg = "Successfull";
if (!task.isSuccessful()) {
msg = "Failed";
}
// Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
For Notification click add Pending intent to notification builder. and for adding image/icon to notification use setSmallIcon() in notification builder. below is my notification code.
private void sendNotification(String body, String title) {
Intent intent = new Intent(this, NotificationActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("action_type", "notify");
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new
NotificationCompat.Builder(this,"channel")
.setSmallIcon(R.drawable.logo)
// .setContent(contentView)
.setContentTitle("title")
.setContentText("body")
.setAutoCancel(true)
.setContentIntent(pendingIntent);
Notification notification = notificationBuilder.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
See below code. Opening Activity.
original post credit
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, HomeActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
I implemented a notification service in my android app (FirebaseMessagingService). When I click a notification, and the app is closed, the wrong activity is opened. If the notification arrives while the app is open (foreground, background), the activity that is opened is correct.
In the following code, the splash activity (first activity of the project) is opened instead of IntroNoti.class.
This is the code of my FireBaseMessagingService class
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
//Log.d(TAG, "From: " + remoteMessage.getFrom());
//Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
Globals.messageIn = true;
sendNotification(remoteMessage);
}
private void sendNotification(RemoteMessage remoteMessage) {
//Intent intent = new Intent(this, Login.class);
Intent intent = new Intent(this, IntroNoti.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.ic_launcher: R.mipmap.ic_launcher;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(icon)
.setContentTitle(remoteMessage.getNotification().getTitle())
.setContentText(remoteMessage.getNotification().getBody())
.setContentText("CIAO CIAO")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
Thanks to the advice of #Eugen Pechanec I added this instruction in my MainActivity. The "messageid" property is only valued when the app is opened by the notification.
Thank you all!
if (getIntent() != null && getIntent().getExtras() != null && getIntent().getExtras().size() > 0) {
Log.d(TAG, "Received extras in onCreate()");
Bundle extras = getIntent().getExtras();
if (!extras.getString("messageid","").isEmpty()) {
Globals.fromNotification = true;
}
}
Use PendingIntent.FLAG_UPDATE_CURRENT flag with pending intent . It's work for me.
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplication(), CHANNEL_ID)
.setSmallIcon(R.drawable.logo)
.setContentTitle(title)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(getPendingIntent())
.setAutoCancel(true);
private PendingIntent getPendingIntent() {
Intent intent = new Intent(getApplication(), ConversationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
return PendingIntent.getActivity(getApplication(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
I have configured the FCM for my 3° application android but in this case the notification is received only if application is closed or background, when app is running nothing appears.
This is my .FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
private void sendNotification(String title, String body) {
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
Intent showFullQuoteIntent = new Intent(this, Home.class);
showFullQuoteIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
// both of these approaches now work: FLAG_CANCEL, FLAG_UPDATE; the uniqueInt may be the real solution.
//PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueInt, showFullQuoteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
int uniqueInt = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueInt, showFullQuoteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(getApplicationContext(), "")
.setSmallIcon(R.drawable.logo)
.setContentTitle(title)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.logo))
.setColor(getResources().getColor(R.color.colorPrimary))
.setAutoCancel(false)
.setSound(notificationSound)
.setContentIntent(pendingIntent)
.setContentText(body)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(m, notification);
}
}
Called in:
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Please can you help me? FCM is linked to my firebase account and i send notification from firebase site...
FCM Log:
D/FA: Logging event (FE): notification_foreground(_nf), Bundle[{firebase_event_origin(_o)=fcm, firebase_screen_class(_sc)=Home, firebase_screen_id(_si)=-8508869816157962301, message_device_time(_ndt)=0, message_name(_nmn)=test, message_time(_nmt)=1521054559, message_id(_nmid)=5215133478455582605}]
I have use some code like:
Notification not showing in Android 8 Oreo
And Guidelines from Google: https://developer.android.com/training/notify-user/build-notification.html
But if application is opened notification not received but logged in console..
I have solved with this code:
private void sendNotification(String title, String body) {
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String CHANNEL_ID = "my_channesl_01";
CharSequence name = "NEWS";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel = null;
mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
mNotificationManager.createNotificationChannel(mChannel);
Intent showFullQuoteIntent = new Intent(this, Home.class);
showFullQuoteIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
int uniqueInt = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueInt, showFullQuoteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(this.getApplicationContext(), "")
.setSmallIcon(R.drawable.logo)
.setContentTitle(title)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.logo))
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setAutoCancel(false)
.setSound(notificationSound)
.setContentIntent(pendingIntent)
.setContentText(body)
.setChannelId(CHANNEL_ID)
.build();
mNotificationManager.notify(m, notification);
}
else
{
Intent showFullQuoteIntent = new Intent(this, Home.class);
showFullQuoteIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
int uniqueInt = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent pendingIntent = PendingIntent.getActivity(this, uniqueInt, showFullQuoteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification notification = new NotificationCompat.Builder(getApplicationContext(), "")
.setSmallIcon(R.drawable.logo)
.setContentTitle(title)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.logo))
.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
.setAutoCancel(false)
.setSound(notificationSound)
.setContentIntent(pendingIntent)
.setContentText(body)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(m, notification);
}
}
I have wired up a notifications action handler with PendingIntent.getBroadcast that shows actions inside the notification. The actions work fine, when I use the default click event on the heads up notification it works fine. My issue comes when the notification is in the tray and I have other notifications in the drawer, I am trying to program the default click/touch event on the notification to broadcast to the receiver and run an action. Here is some code:
Uri alertSound = Uri.parse("android.resource://" + ctx.getPackageName() + "/raw/page_the_doctor");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setAutoCancel(true)
.setSmallIcon(R.mipmap.telemed_logo)
.setContentTitle("PATIENT READY")
.setContentText(notification)
.setDefaults( Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setSound( alertSound )
.setPriority(Notification.PRIORITY_MAX)
.setAutoCancel(true);
//CLICK ON NOTIFICATION HERE ONLY WORKS ON HEADS UP AND NOT DEFAULT
Intent notificationIntent = new Intent(ctx, PushNotificationActions.class);
notificationIntent.putExtra("visitId", visitId);
notificationIntent.putExtra("link", link);
notificationIntent.setAction(ACCEPT_EXAM);
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(clickIntent);
//Accept intent action works fine
Intent acceptExam = new Intent(ctx, PushNotificationActions.class);
acceptExam.setAction(ACCEPT_EXAM);
acceptExam.putExtra("visitId", visitId);
acceptExam.putExtra("link", link);
PendingIntent pendingAcceptIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), acceptExam, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(R.drawable.accept_action_24dp, "ACCEPT", pendingAcceptIntent);
//Dismiss intent action works fine
Intent dismissExam = new Intent(ctx, PushNotificationActions.class);
dismissExam.setAction(DISMISS_EXAM);
dismissExam.putExtra("visitId", visitId);
dismissExam.putExtra("link", link);
PendingIntent pendingDismissIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), dismissExam, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(R.drawable.dismiss_action_24dp, "DISMISS", pendingDismissIntent);
Notification noti = notificationBuilder.build();
noti.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(Integer.parseInt(visitId), noti);
Here is the onReceive method:
private Context context;
#Override
public void onReceive(Context ctx, final Intent intent) {
Log.d("PushNotificationActions","Started");
String action = intent.getAction();
Log.d("<-------------------<<<", "getaction is: " + action);
context = ctx;
if (ACCEPT_EXAM.equals(action)) {
Log.d("ACCEPT_ACTION", "READY FOR EXAM NOW");
Map<String, String> params = new HashMap();
params.put("email", email);
final JSONObject parameters = new JSONObject(params);
Log.d("parameters: ", parameters.toString());
volleyJsonObjectPost("ws", parameters, new Login.ServerCallback() {
public void onSuccess(JSONObject response) {
try {
final JSONObject loginData = response.getJSONObject("d");
DataModel.sharedInstance().key = loginData.getString("key");
final String visitLink; String link; final String visitId; Bundle extras = intent.getExtras();
if(extras != null) {
link = extras.getString("link");
visitId = extras.getString("visitId");
visitLink = link + loginData.getString("key") + ',' + visitId;
JSONObject params = new JSONObject();
params.put("key", loginData.getString("key"));
Log.d("params: ", params.toString());
volleyJsonObjectPost("ws", params, new Login.ServerCallback() {
public void onSuccess(JSONObject result) {
try {
final JSONObject acceptExamResultData = result.getJSONObject("d");
Log.d("acceptExamResultData: ", acceptExamResultData.toString());
if (acceptExamResultData.getBoolean("status") == true) {
Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(visitLink));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setPackage("com.android.chrome");
try {
context.startActivity(intent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(Integer.parseInt(visitId));
} catch (ActivityNotFoundException ex) {
// Chrome browser presumably not installed so allow user to choose instead
intent.setPackage(null);
context.startActivity(intent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(Integer.parseInt(visitId));
Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(closeIntent);
}
}else {
// Exam was already accepted by another Doc
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}else if (DISMISS_EXAM.equals(action)) {
Log.d("DISMISS_ACTION", "I CANNOT TAKE THIS EXAM");
String visitId; Bundle extras = intent.getExtras();
if(extras != null) {
visitId = extras.getString("visitId");
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Log.d("Visit ID to cancel", visitId);
mNotificationManager.cancel(Integer.parseInt(visitId));
Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(closeIntent);
}
}
Here is the receiver in the manifest:
<receiver android:name=".PushNotificationActions" >
<intent-filter>
<action android:name="com.Telemed.app.ACCEPT_EXAM" />
<action android:name="com.Telemed.app.DISMISS_EXAM" />
</intent-filter>
</receiver>
Since the notification won't slide easy in the drawer in most cases I need this default functionality to mirror the Accept Exam Action. Only I don't want it to be an action, I just want it to work when the user clicks on the notification. I need to use getBroadcast because I am making a web service call (async) to get some data I need to do the next step
So in order to set the default functionality for the notification you have to create a default pending intent before constructing your notification builder:
Like so:
//CLICK ON NOTIFICATION
Intent notificationIntent = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Now after that set this:
.setContentIntent(clickIntent)
in the new NotificationCompat.Builder. After that you can set up as many actions as you want but the default will still access your action and act as a default in the case where the drawer sticks your notification at the to and you cannot see your programmed actions.
Uri alertSound = Uri.parse("android.resource://" + ctx.getPackageName() + "/raw/page_the_doctor");
//CLICK ON NOTIFICATION
Intent notificationIntent = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setAutoCancel(true)
.setSmallIcon(R.mipmap.telemed_logo)
.setContentTitle("TELEMED PATIENT READY")
.setContentText(notification)
.setDefaults( Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setSound( alertSound )
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(clickIntent)
.setAutoCancel(true);
//Accept intent
Intent acceptExam = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
PendingIntent pendingAcceptIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), acceptExam, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(R.drawable.accept_action_24dp, "ACCEPT", pendingAcceptIntent);
//Dismiss intent
Intent dismissExam = new Intent(ctx, PushNotificationActions.class).setAction(DISMISS_EXAM).putExtra("visitId", visitId).putExtra("link", link);
PendingIntent pendingDismissIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), dismissExam, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.addAction(R.drawable.dismiss_action_24dp, "DISMISS", pendingDismissIntent);
Notification noti = notificationBuilder.build();
noti.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(Integer.parseInt(visitId), noti);