I have a Firebase service that creates notifications on data messages.
It looks like
public class KaliumMessagingService extends FirebaseMessagingService {
private static final String TAG = KaliumMessagingService.class.getSimpleName();
private static final String NOTIFICATION_CHANNEL_ID = "natrium_notification_channel";
private final String NOTIF_GROUP_ID = "NATRIUM_NOTIF_GROUP";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData() != null && !MainActivity.appInForeground) {
sendNotification(remoteMessage);
}
}
#Override
public void onNewToken(String token) {
super.onNewToken(token);
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(this);
sharedPreferencesUtil.setFcmToken(token);
}
public void initChannels(Context context) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Natrium transaction alerts");
notificationManager.createNotificationChannel(channel);
}
private void sendNotification(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String amount = data.get("amount");
if (amount == null) {
return;
}
initChannels(this);
try (Realm realm = Realm.getDefaultInstance()) {
Credentials c = realm.where(Credentials.class).findFirst();
// If not logged in, shouldn't post notifications
if (c == null) {
return;
}
}
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.ic_status_bar);
builder.setContentText(getString(R.string.notification_body));
builder.setContentTitle(getString(R.string.notification_title, NumberUtil.getRawAsUsableString(amount)));
builder.setAutoCancel(true);
builder.setGroup(NOTIF_GROUP_ID);
builder.setSound(defaultSoundUri);
Notification pushNotification = builder.build();
nm.notify((int)System.currentTimeMillis(), pushNotification);
}
}
It works but, all the notifications are separate. I'd like them all to be grouped together/expandable. And clicking on it opens the main activity and dismisses all notifications.
I thought setGroup would achieve this behavior, but it hasn't seemed to make any difference.
Thanks
I ended up solving it as described in this blog post
https://blog.hopbucket.com/merge-firebase-notifications-9f96de7d026a
public class KaliumMessagingService extends FirebaseMessagingService {
private static final String TAG = KaliumMessagingService.class.getSimpleName();
private static final String NOTIFICATION_CHANNEL_ID = "natrium_notification_channel";
private int NOTIFICATION_ID = 1337;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(this);
if (remoteMessage.getData() != null && !MainActivity.appInForeground && sharedPreferencesUtil.getNotificationSetting() != NotificationOption.OFF) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
sendNotification(remoteMessage);
} else {
sendNotificationLegacy(remoteMessage);
}
}
}
#Override
public void onNewToken(String token) {
super.onNewToken(token);
SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(this);
sharedPreferencesUtil.setFcmToken(token);
}
public void initChannels(Context context) {
if (Build.VERSION.SDK_INT < 26) {
return;
}
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Natrium transaction alerts");
notificationManager.createNotificationChannel(channel);
}
private void sendNotificationLegacy(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String amount = data.get("amount");
if (amount == null) {
return;
}
initChannels(this);
try (Realm realm = Realm.getDefaultInstance()) {
Credentials c = realm.where(Credentials.class).findFirst();
// If not logged in, shouldn't post notifications
if (c == null) {
return;
}
}
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,0,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.ic_status_bar);
builder.setContentText(getString(R.string.notification_body));
builder.setContentTitle(getString(R.string.notification_title, NumberUtil.getRawAsUsableString(amount)));
builder.setAutoCancel(true);
builder.setGroup(TAG);
builder.setSound(defaultSoundUri);
Notification pushNotification = builder.build();
nm.notify((int)System.currentTimeMillis(), pushNotification);
}
#TargetApi(Build.VERSION_CODES.M)
private void sendNotification(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String amount = data.get("amount");
if (amount == null) {
return;
}
initChannels(this);
try (Realm realm = Realm.getDefaultInstance()) {
Credentials c = realm.where(Credentials.class).findFirst();
// If not logged in, shouldn't post notifications
if (c == null) {
return;
}
}
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
Intent onCancelNotificationReceiver = new Intent(this, CancelNotificationReceiver.class);
PendingIntent onCancelNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0,
onCancelNotificationReceiver, 0);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
StatusBarNotification[] notifications = manager.getActiveNotifications();
for (int i = 0; i < notifications.length; i++) {
if (notifications[i].getPackageName().equals(getApplicationContext().getPackageName())) {
Intent startNotificationActivity = new Intent(this, MainActivity.class);
startNotificationActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, startNotificationActivity,
PendingIntent.FLAG_ONE_SHOT);
Notification notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_status_bar)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(getString(R.string.notification_title, NumberUtil.getRawAsUsableString(amount)))
.setContentText(getString(R.string.notification_body))
.setAutoCancel(true)
.setStyle(getStyleForNotification(getString(R.string.notification_body)))
.setGroupSummary(true)
.setGroup(TAG)
.setContentIntent(pendingIntent)
.setDeleteIntent(onCancelNotificationReceiverPendingIntent)
.build();
SharedPreferences sharedPreferences = getSharedPreferences("NotificationData", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(String.valueOf(new Random(NOTIFICATION_ID)), getString(R.string.notification_body));
editor.apply();
notificationManager.notify(NOTIFICATION_ID, notification);
return;
}
}
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Notification notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_status_bar)
.setContentTitle(getString(R.string.notification_title, NumberUtil.getRawAsUsableString(amount)))
.setContentText(getString(R.string.notification_body))
.setAutoCancel(true)
.setGroup(TAG)
.setContentIntent(pendingIntent)
.setDeleteIntent(onCancelNotificationReceiverPendingIntent)
.build();
SharedPreferences sharedPreferences = getSharedPreferences("NotificationData", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(String.valueOf(new Random(NOTIFICATION_ID)), getString(R.string.notification_body));
editor.apply();
notificationManager.notify(NOTIFICATION_ID, notificationBuilder);
}
private NotificationCompat.InboxStyle getStyleForNotification(String messageBody) {
NotificationCompat.InboxStyle inbox = new NotificationCompat.InboxStyle();
SharedPreferences sharedPref = getSharedPreferences("NotificationData", 0);
Map<String, String> notificationMessages = (Map<String, String>) sharedPref.getAll();
Map<String, String> myNewHashMap = new HashMap<>();
for (Map.Entry<String, String> entry : notificationMessages.entrySet()) {
myNewHashMap.put(entry.getKey(), entry.getValue());
}
inbox.addLine(messageBody);
for (Map.Entry<String, String> message : myNewHashMap.entrySet()) {
inbox.addLine(message.getValue());
}
inbox.setBigContentTitle(this.getResources().getString(R.string.app_name))
.setSummaryText(getString(R.string.notificaiton_header_suplement));
return inbox;
}
}
Related
I have trouble but don't understand why it's happened, I have two type notification in app, ChatNotification and PostNotification, after add new post, i get this error:
give me error in line if (notificationType.equals("PostNotification")){
E/AndroidRuntime: FATAL EXCEPTION: Firebase-Messaging-Intent-Handle
Process: com.example.chatbox, PID: 24011
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.example.chatbox.notifications.FirebaseMessaging.onMessageReceived(FirebaseMessaging.java:58)
at com.google.firebase.messaging.FirebaseMessagingService.zzc(com.google.firebase:firebase-messaging##20.2.0:80)
at com.google.firebase.messaging.zzh.run(com.google.firebase:firebase-messaging##20.2.0:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement##17.1.1:6)
at java.lang.Thread.run(Thread.java:764)
public class FirebaseMessaging extends FirebaseMessagingService {
private static final String ADMIN_CHANNEL_ID = "admin_channel";
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
//get current user from shared preferences
SharedPreferences sp = getSharedPreferences("SP_USER", MODE_PRIVATE);
String savedCurrentUser = sp.getString("Current_USERID", "None");
/*we have two type notification
> notificationType ="PostNotification"
> notificationType ="ChatNotification"*/
String notificationType = remoteMessage.getData().get("notificationType");
if (notificationType.equals("PostNotification")){
//post notification
String sender = remoteMessage.getData().get("sent");
String pId = remoteMessage.getData().get("id");
String pTitle = remoteMessage.getData().get("name");
String pDescription = remoteMessage.getData().get("description");
//if user is same that has post don't show notification
if (!sender.equals(savedCurrentUser)){
showPostNotification("" + pId, "" + pTitle, "" + pDescription);
}
}
else if (notificationType.equals("ChatNotification")){
//chat notification
String sent = remoteMessage.getData().get("sent");
String user = remoteMessage.getData().get("user");
FirebaseUser fUser = FirebaseAuth.getInstance().getCurrentUser();
if (fUser != null && sent.equals(fUser.getUid())) {
if (!savedCurrentUser.equals(user)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
sendOAndAboveNotification(remoteMessage);
} else {
sendNormalNotification(remoteMessage);
}
}
}
}
}
private void showPostNotification(String pId, String pTitle, String pDescription) {
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = new Random().nextInt(3000);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
setupPostNotificationChannel(notificationManager);
}
//show post detail activity using post id when notification clicked
Intent intent = new Intent(this, ClickPostActivity.class);
intent.putExtra("PostKey", pId);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
//largeIcon
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.default_avatar);
//sound for notification
Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "" + ADMIN_CHANNEL_ID)
.setSmallIcon(R.drawable.default_avatar)
.setLargeIcon(largeIcon)
.setContentTitle(pTitle)
.setContentText(pDescription)
.setSound(notificationSoundUri)
.setContentIntent(pendingIntent);
//show notification
notificationManager.notify(notificationID, notificationBuilder.build());
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setupPostNotificationChannel(NotificationManager notificationManager) {
CharSequence channelName = "New Notification";
String channelDescription = "Device to device post notification";
NotificationChannel adminChannel = new NotificationChannel(ADMIN_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
adminChannel.setDescription(channelDescription);
adminChannel.enableLights(true);
adminChannel.setLightColor(Color.RED);
adminChannel.enableVibration(true);
if (notificationManager!=null){
notificationManager.createNotificationChannel(adminChannel);
}
}
private void sendNormalNotification(RemoteMessage remoteMessage) {
String user = remoteMessage.getData().get("user");
String icon = remoteMessage.getData().get("icon");
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
RemoteMessage.Notification notification = remoteMessage.getNotification();
int i = Integer.parseInt(user.replaceAll("[\\D]", ""));
Intent intent = new Intent(this, ChatActivity.class);
Bundle bundle = new Bundle();
bundle.putString("visit_user_id", user);
intent.putExtras(bundle);
PendingIntent pIntent = PendingIntent.getActivity(this, i, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(Integer.parseInt(icon))
.setContentText(body)
.setContentTitle(title)
.setAutoCancel(true)
.setSound(defSoundUri)
.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int j = 0;
if (i > 0) {
j = 1;
}
notificationManager.notify(j, builder.build());
}
#TargetApi(Build.VERSION_CODES.O)
private void sendOAndAboveNotification(RemoteMessage remoteMessage) {
String user = remoteMessage.getData().get("user");
String icon = remoteMessage.getData().get("icon");
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
RemoteMessage.Notification notification = remoteMessage.getNotification();
int i = Integer.parseInt(user.replaceAll("[\\D]", ""));
Intent intent = new Intent(this, ChatActivity.class);
Bundle bundle = new Bundle();
bundle.putString("visit_user_id", user);
intent.putExtras(bundle);
PendingIntent pIntent = PendingIntent.getActivity(this, i, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
OreoAndAboveNotification notification1 = new OreoAndAboveNotification(this);
Notification.Builder builder = notification1.getONotificatios(title, body, pIntent, defSoundUri, icon);
int j = 0;
if (i > 0) {
j = 1;
}
notification1.getManager().notify(j, builder.build());
}
#Override
public void onNewToken(#NonNull String s) {
super.onNewToken(s);
//update user yoken
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
//signed in, update token
updateToken(s);
}
}
private void updateToken(String tokenRefresh) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Tokens");
Token token = new Token(tokenRefresh);
ref.child(user.getUid()).setValue(token);
}
}
I need help from the guru :) or any help, to solved this problem
How can I set Large Icon to notification? I getting URL of the Image in timetable.getImage(). In my project, Picasso supports get() method, not with().
I am new in android, please help.
You can see my notififcation on picture below. Icon image of notification is hardcoded. But I need this icon image from timetable.getImage().
This is my code:
public class EpisodeNotifyActivity extends AppCompatActivity {
private NotificationManagerCompat notificationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ativity_episode_notify);
final Timetable timetable = (Timetable) requestService.getResult();
ImageView serImage = (ImageView) findViewById(R.id.seriesImage1);
Button button = findViewById(R.id.notify);
Picasso.get()
.load(timetable.getImage())
.into(serImage);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification(timetable.getSeriesName().toUpperCase() + ", New Episode", timetable.getEpisodesSeason().toString() + "x" + timetable.getEpisodesNumber() + " " + timetable.getEpisodeName());
} }); }
private void sendNotification(String messageTitle, String messageBody) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, EpisodeNotifyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
#SuppressLint("WrongConstant")
NotificationChannel notificationChannel = new NotificationChannel("my_notification", "n_channel", NotificationManager.IMPORTANCE_MAX);
notificationChannel.setDescription("description");
notificationChannel.setName("Channel Name");
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_live_tv_black_24dp)
.setContentTitle(messageTitle)
// .setLargeIcon(R.drawable.icon)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setOnlyAlertOnce(true)
.setChannelId("my_notification")
.setColor(Color.parseColor("#3F5996"));
assert notificationManager != null;
int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
notificationManager.notify(m, notificationBuilder.build());
}
}}
public class EpisodeNotifyActivity extends AppCompatActivity {
private NotificationManagerCompat notificationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ativity_episode_notify);
final Timetable timetable = (Timetable) requestService.getResult();
ImageView serImage = (ImageView) findViewById(R.id.seriesImage1);
Button button = findViewById(R.id.notify);
Picasso.get()
.load(timetable.getImage())
.into(serImage);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, EpisodeNotifyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
#SuppressLint("WrongConstant")
NotificationChannel notificationChannel = new NotificationChannel("my_notification", "n_channel", NotificationManager.IMPORTANCE_MAX);
notificationChannel.setDescription("description");
notificationChannel.setName("Channel Name");
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel);
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_live_tv_black_24dp)
.setContentTitle(timetable.getSeriesName().toUpperCase() + ", New Episode")
.setContentText(timetable.getEpisodesSeason().toString() + "x" + timetable.getEpisodesNumber() + " " + timetable.getEpisodeName())
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setOnlyAlertOnce(true)
.setChannelId("my_notification")
.setColor(Color.parseColor("#3F5996"));
Picasso.get().load(timetable.getImage())
.into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// !!!!!!!! MAGIC HAPPENS HERE
notificationBuilder.setLargeIcon(bitmap);
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification();
}
});
}
}
private void sendNotification() {
assert notificationManager != null;
int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
notificationManager.notify(m, notificationBuilder.build());
}
}
I'm new to developing an application. Currently, I'm working on push notification. Before this, I'm trying using Android 4.4, and the push notification work just fine. But, now I'm trying to debug on my Android 9 (Pie), but it seems like the notification does not appear.
I already try a few solutions. They suggest to use a notification channel for Android 8 and above. I have tried some of the solution from here: Previous question answer and here Previous question answer.
But, I don't know why it does not work for me.
Here is my code
public void onReceive(final Context context, final Intent intent) {
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationId = 1;
String channelId = "channel-01";
String channelName = "Channel Name";
int importance = NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
channelId, channelName, importance);
nm.createNotificationChannel(mChannel);
}
if (!intent.getExtras().getBoolean("cancel", false)) {
this.context = context;
prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
notification = new NotificationCompat.Builder(context, channelId);
count = intent.getExtras().getInt("count");
name = prefs.getString("name"+count, "");
hours = prefs.getInt("hora"+count, 8);
minutes = prefs.getInt("minuto"+count, 0);
minutesBefore = prefs.getInt("minutesBefore", 30);
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH)
isScreenOn = pm.isInteractive();
else
isScreenOn = pm.isScreenOn();
if (!isScreenOn) {
#SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");
wl.acquire(10000);
#SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyCpuLock");
wl_cpu.acquire(10000);
}
/**
* notification
*/
final Intent notificationIntent = new Intent(context, Broadcast_TakenAction.class);
//Broadcast_TakenAction gets called when notification is clicked
notificationIntent.putExtra("count", count);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pIntent = PendingIntent.getBroadcast(context, count, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setAutoCancel(true);
notification.setLargeIcon(drawableToBitmap(ResourcesCompat.getDrawable(context.getResources(), R.drawable.notification_large_icon, null)));
notification.setSmallIcon(R.drawable.small_icon);
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle(name);
notification.setContentIntent(pIntent);
notification.setPriority(0);
notification.addAction(R.drawable.check, "Taken", pIntent);
if (intent.getExtras().getBoolean("shownBefore", false)) {
Runnable delayedThreadStartTask2 = new Runnable() {
#Override
public void run() {
new Thread(
new Runnable() {
#Override
public void run() {
for (int incr = 0; incr < minutesBefore; incr++) {
if (!intent.getExtras().getBoolean("cancel", false)) {
int time_left = minutesBefore - incr;
notification.setContentText(time_left + "m left.");
nm.notify(count, notification.build());
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException ignored) {
}
}
}
realNotification();
if (prefs.getBoolean("vibrates", true)) {
Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
}
}
}
).start();
}
};
delayedThreadStartTask2.run();
} else {
realNotification();
}
}
}
I'm not sure what wrong with my code. Please correct me if I'm wrong.
this code worked for me in any API number:
public void Notificate() {
try {
final String NOTIFICATION_CHANNEL_ID = "10001";
String notification_title = getResources().getString(R.string.label);
String notification_message =jsonArray.get(4).getAsString() ;
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(ActivityMain.this)
.setSmallIcon(R.drawable.tahlil)
.setContentTitle(notification_title)
.setContentText(notification_message)
.setAutoCancel(true)
.setVibrate(new long[]{100, 200, 300, 400})
.setSound(alarmSound);
Intent resultIntent = new Intent(getApplicationContext(), ActivityChatList.class);
resultIntent.putExtra("menuFragment", "favoritesMenuItem");
// resultIntent.putExtra("user_id", from_user_id);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
getApplicationContext(),
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT
);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationId = System.currentTimeMillis();
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
if (mNotifyMgr != null) {
mNotifyMgr.createNotificationChannel(notificationChannel);
}
}
if (mNotifyMgr != null) {
mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
} catch (Exception e) {
}
}
I am sending a notification into my app using Firebase cloud messaging and it's working fine. However, when I send a notification and if my app is in the foreground, the notification will not show in the notification tray. The notification only shows in the notification tray if my app is in the background.
Below is my code:
public class Notifications extends FirebaseMessagingService {
#ServerTimestamp
Date time;
private FirebaseFirestore mFirestore;
private boolean isNotificationMatching = false;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
mFirestore = FirebaseFirestore.getInstance();
if (remoteMessage.getData() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
sendNotificationAPI26(remoteMessage);
else
sendNotification(remoteMessage);
}
}
private void sendNotification(RemoteMessage remoteMessage) {
isNotificationMatching = false;
Intent intent = new Intent(this, Dashboard.class);
intent.putExtra("notificationFragment", "showNotifications");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
final Map<String, String> data = remoteMessage.getData();
String title = data.get("title");
mFirestore.collection("notifications").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (document.getData().get("id").equals(id)) {
isNotificationMatching = true;
break;
}
}
if (!isNotificationMatching) {
postDataToFirebaseServer(data);
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.app_logo)
.setContentText(description)
.setAutoCancel(true)
.setSound(defaultSoundUri);
builder.setContentIntent(pendingIntent);
NotificationManager noti = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
noti.notify(new Random().nextInt(), builder.build());
}
private void postDataToFirebaseServer(Map<String, String> data) {
Map<String, Object> postDataMap = new HashMap<>();
postDataMap.put("title", data.get("title"));
postDataMap.put("timestamp", FieldValue.serverTimestamp());
mFirestore.collection("notifications").add(postDataMap).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
// Toast.makeText(getA.this, "Success", Toast.LENGTH_SHORT);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
String error = e.getMessage();
// Toast.makeText(Testing.this, "Failed", Toast.LENGTH_SHORT);
}
});
}
private void sendNotificationAPI26(RemoteMessage remoteMessage) {
Intent intent = new Intent(this, Dashboard.class);
intent.putExtra("notificationFragment", "showNotifications");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
final Map<String, String> data = remoteMessage.getData();
String title = data.get("title");
mFirestore.collection("notifications").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
if (document.getData().get("id").equals(id)) {
isNotificationMatching = true;
break;
}
}
if (!isNotificationMatching) {
postDataToFirebaseServer(data);
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
NotificationHelper helper;
Notification.Builder builder;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
helper = new NotificationHelper(this);
builder = helper.getLootBoxNotification(title, defaultSoundUri);
helper.getManager().notify(new Random().nextInt(), builder.build());
builder.setContentIntent(pendingIntent);
}
}
This is your code
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.app_logo)
.setContentText(description)
.setAutoCancel(true)
.setSound(defaultSoundUri);
builder.setContentIntent(pendingIntent);
Here you have set is as
setAutoCancel(true);
This method will cancel all the notification while your app is in foreground.
Set it to false.
I am registering a broadcast receiver from a service. I need to show notification to user if location of device is off the code works fine but receiver does not create notification. I can see logcat messages on changing location status but notification is not created Please check the issue ! And is there any way to update the current notification of the service?
This is Service:
public class LockService extends Service {
BroadcastReceiver mReceiver;
Handler handler;
LocationManager locationManager;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private static final int NOTIF_ID = 1;
#Override
public void onCreate() {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
mReceiver = new com.example.fizatanveerkhan.citycops.ScreenReceiver();
registerReceiver(mReceiver, filter);
super.onCreate();
}
private void startForeground() {
startForeground(NOTIF_ID, getMyActivityNotification(""));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.startForeground();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
Log.i("onDestroy Reciever", "Called");
}
super.onDestroy();
}
public class LocalBinder extends Binder {
LockService getService() {
return LockService.this;
}
}
private Notification getMyActivityNotification(String text) {
CharSequence title = "new";
Notification notification = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = " com.example.fizatanveerkhan.citycops";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
}
return notification;
}
/* public void updateNotification() {
String text = "Some text that will update the notification";
Notification notification = getMyActivityNotification(text);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIF_ID, notification);
}*/
}
And this is broadcast receiver:
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
private static final int POWER_OFF_TIMEOUT = 500;
private Handler handler = new Handler();
private Runnable powerOffCounterReset = new PowerOfTimeoutReset();
private int countPowerOff = 0;
private boolean screenOff;
//private LockService updateService = new LockService();
private final static String TAG = "LocationProviderChanged";
boolean isGpsEnabled;
boolean isNetworkEnabled;
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Log.i(TAG, "Location Providers changed");
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//Start your Activity if location was enabled:
if (isGpsEnabled || isNetworkEnabled) {
Log.i(TAG, "Location Providers on");
}
else {
Log.i(TAG, "Location Providers off");
Notification notification = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = " com.example.fizatanveerkhan.citycops";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, notification);
}
}
}
I can see logcat messages on changing location status but notification is not created
Changing notification code to this solved the problem
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = "
com.example.fizatanveerkhan.citycops";
CharSequence name = "My Background Service";
String description = "My Background Service";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
NotificationManagerCompat notificationManagerq =
NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManagerq.notify(1, notificationBuilder.build());
}
So basically you need to create a foreground notification and update its contents on location change.
You can use the code below to create a foreground notification:-
//for foreground service notification
public Notification showForegroundNotification(String notificationTitle, String notificationBody, Intent intent, ServiceName serviceName) {
String id = mContext.getString(R.string.upload_notification_channel_id);
PendingIntent lowIntent = PendingIntent.getActivity(mContext, 100, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, id);
NotificationManager mNotifyManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = mContext.getString(R.string.upload_notification_channel_name);
String description = mContext.getString(R.string.upload_notification_channel_description); //user visible
int importance = NotificationManager.IMPORTANCE_LOW;
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
mChannel.setDescription(description);
mChannel.enableLights(false);
mChannel.enableVibration(false);
mChannel.setVibrationPattern(new long[]{0L});
mChannel.setSound(null, att);
if (mNotifyManager != null) {
mNotifyManager.createNotificationChannel(mChannel);
}
notificationBuilder
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVibrate(new long[]{0L})
.setSound(null)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
.setContentTitle(notificationTitle)
.setAutoCancel(true)
.setContentIntent(lowIntent);
} else {
notificationBuilder.setContentTitle(notificationTitle)
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVibrate(new long[]{0L})
.setSound(null)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
.setAutoCancel(true)
.setContentIntent(lowIntent);
}
if (notificationBody != null) {
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(notificationBody));
}
notificationBuilder.setContentText(notificationBody);
return notificationBuilder.build();
}
and you need to call startForegroundService();
private void startForegroundService(){
String dataTitle = SharedPrefer.getLastUpdatedLocationName();
String dataContent = SharedPrefer.getLastUpdatedLocation();
Intent intent = new Intent(WITHU.getAppContext(), MapLocateActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startForeground(121, showNotification.showForegroundNotification(dataTitle, dataContent, intent, ServiceName.SMART_LOCATION, -1, false));
}
So it will pass the updated location name and location which you can collect from SharedPreference or also can be called directly onLocationChanged.