I am trying to send a int Extra to an Activity when a notification is tapped. When I tap the notification the activity launches, but the extra is always null.
I have checked a lot of similar questions but they haven't helped me solve the problem. (I tried using onNewIntent() but it was never called). How can I successfully send the Extra?
This is the BroadcastReceiver where the intent is created:
public class EventAlarmNearReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent nextIntent = new Intent().setClass(context, EventActivity.class);
nextIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int id = 1234;
nextIntent.putExtra("Id", (long) id);
nextIntent.setAction("nearReceiverAction");
PendingIntent nextPendingIntent = PendingIntent.getActivity(context, 1022, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
String text = "Your " + intent.getStringExtra("Name") + " is starting soon. Please read your documents.";
NotificationsDeliver.getInstance().sendNotification(context, "Meeting Mate", text, nextPendingIntent);
}
}
This is the method from NotificationsDeliver where the notification is sent:
public void sendNotification(#NonNull Context context, String title, String text, PendingIntent pendingIntent ) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_event_note_white_24dp)
.setContentTitle(title)
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[] { 1000, 1000, 1000 })
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(999, builder.build());
}
This is onCreate method from EventActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
long id = intent.getLongExtra("id", 0);
}
I would guess that it's because you have capitalized the word "id" differently when putting vs getting the extra; compare:
nextIntent.putExtra("Id", (long) id);
// ^^^^
vs
long id = intent.getLongExtra("id", 0);
// ^^^^
Try using the same capitalization for both.
Related
I am trying to send a notification at a specific time after registering an item on a database (6 hours or 12 hours). The notification works fine when I only register one item, however if I register 2 items in a close period of time the first notification is overwritten by the second.
I know that I have to add ID's to the pending intents and maybe an id to the actual notification however I am not very familiar with the alarmManager class and I do not know where I should be adding the IDs.
How do I make these two notifications independent of one another?
NotificationHelper Class:
public static class NotificationHelper extends ContextWrapper {
public static final String channel1ID = "channel1ID";
public static final String channel1Name = "USER1";
private NotificationManager mManager;
public NotificationHelper(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannels();
}
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void createChannels() {
NotificationChannel channel1 = new NotificationChannel(channel1ID, channel1Name, NotificationManager.IMPORTANCE_HIGH);
channel1.enableLights(true);
channel1.enableVibration(true);
channel1.shouldVibrate();
channel1.setShowBadge(true);
channel1.setLightColor(R.color.colorPrimary);
channel1.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.setUsage(USAGE_NOTIFICATION)
.build();
channel1.setSound(uri, audioAttributes);
getManager().createNotificationChannel(channel1);
}
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
public NotificationCompat.Builder getChannel1Notification() {
return new NotificationCompat.Builder(getApplicationContext(), channel1ID)
.setContentTitle("Dressing")
.setContentText("Please scan the dressing on your: " + (et_DressingPos.getText().toString().trim()))
.setSmallIcon(R.drawable.ic_cnoticiation_scan);
}
}
AlarmReceiver Class:
#Override
public void onReceive(Context context, Intent intent) {
Camera2Register.NotificationHelper notificationHelper = new Camera2Register.NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannel1Notification();
Intent intent2 = new Intent(context, Camera2.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent2, 0);
nb.setContentIntent(pendingIntent);
notificationHelper.getManager().notify(1, nb.build());
}
}
startAlarmScan and startALarmChange Methods:
private void startAlarmScan() {
int requestCode = ("someString" + System.currentTimeMillis()).hashCode();
Long time = System.currentTimeMillis();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("randomRequestCode", requestCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
long milliseconds = 5000;
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, (time + milliseconds), pendingIntent);
//}
}
private void startAlarmChange() {
int requestCode = ("someString" + System.currentTimeMillis()).hashCode();
Long time = System.currentTimeMillis();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("randomRequestCode", requestCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
long milliseconds = 30000;
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, (time + milliseconds), pendingIntent2);
//}
}
I have set the time delay for the two different notifications to 5 and 30 seconds. If register and class the two startAlarmScan and startAlarmChange methods within 30 seconds of each other. the first scheduled notification will be overwritten by the second.
I am beginning to think the problem may lie in the structuring of my notification system, is a Receiver class necessary? There is no mention of it in the notification documentation on Android.
You are using a constant value "1" for your notification id here: notificationHelper.getManager().notify(1, nb.build());
from the docs: Here "If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information"
Change this 1 to a unique number for each notification and you should see them all come through.
Edit
You also do the same thing on the line:
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent2, 0);
That request code "1" is used to compare pending intents using filterEquals(Intent intent) This question talks about it.
In my application i want open custom activity (not MainActivity) and putExtra to this activity when click on Firebase notification.
I write below codes, but when click on notification open MainActivity, But i want open my another activity (AuctionDetailActivity).
My NotificationManager class :
public class MyNotificationManager {
private Context mCtx;
private Uri soundUri;
private static MyNotificationManager mInstance;
public MyNotificationManager(Context context) {
mCtx = context;
}
public static synchronized MyNotificationManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new MyNotificationManager(context);
}
return mInstance;
}
public void displayNotification(String title, String body) {
soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent = new Intent(mCtx, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("fcm_notification", "Y");
PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx, Constants.NOTIF_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setSound(soundUri)
.setAutoCancel(true)
.setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400})
.setContentText(body)
.setContentIntent(pendingIntent);
NotificationManager mNotifyMgr = (NotificationManager) mCtx.getSystemService(NOTIFICATION_SERVICE);
if (mNotifyMgr != null) {
mNotifyMgr.notify(1, mBuilder.build());
}
}
}
And MyFirebaseMessagingService class :
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
showNotify(remoteMessage.getFrom(), remoteMessage.getNotification().getBody());
}
private void showNotify(String title, String body) {
MyNotificationManager myNotificationManager = new MyNotificationManager(getApplicationContext());
//myNotificationManager.displayNotification(title, body);
myNotificationManager.displayNotification(title, body);
}
}
MainActivity codes:
#Override
protected void onResume() {
super.onResume();
String fcm_notification = getIntent().getStringExtra("fcm_notification");
Log.d("FireBaseIntentLog", " FCM : " + fcm_notification);
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d("FireBaseIntentLog", "Key: " + key + " Value: " + value + " FCM : " + fcm_notification);
}
}
}
How can i fix it?
If you are sending the notification from Firebase console or inside the notification field using FCM API, the app behaves in two ways -
If your app is in foreground, the method onMessageReceived of your FCM service class will be called.
If your app is in background, nothing will happen inside your FCM service class. Rather, the notification will be handled internally by the FCM library itself and the notification with launcher activity in the intent will be shown.
And if you use FCM API to send notification and use the data field, the library does nothing itself and instead calls the method onMessageReceived regardless of whether your app is in foreground or background.
So in order to solve your issue, you can use one of the following two solutions:
Use FCM API to send notifications and use the data field instead of the notification field. Check the documentation to read more about FCM API.
In your launcher (main) activity, check for intent inside onCreate and if it is coming from notification, read the extras, finish the main activity and open your required activity.
Example for second case:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkIntent()) return;
// other code.
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
checkIntent();
}
private boolean checkIntent() {
// to receive the value, send the value as custom data from Firebase console.
String value = getIntent().getStringExtra("your_key");
if (value == null) return false;
if (value.equals("something")) {
// open one activity.
} else if (value.equals("another_thing")) {
// open another activity.
}
finish();
return true;
}
Change this below line
Intent intent = new Intent(click_action);
to this
Intent intent = new Intent(getActivity(), YourClass.class);
You just need modify in sendNotification function
public void sendNotification(String messageBody, String messageTitle, int user_id, String click_action) {
Intent intent = new Intent(mCtx, AuctionDetailActivity.class); // Need modify this line
intent.putExtra(Extras.bidID.name(), user_id);
PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mCtx, Constants.NOTIF_CHANNEL_ID);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) mCtx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
Change your MyFirebaseMessagingService class as shown below replace OtherApp.class with your activity name
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent intent=new Intent(this,OtherApp.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);//newbg PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder= new NotificationCompat.Builder(this);
notificationBuilder.setContentTitle("FCM NOTIFICATION"); notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,notificationBuilder.build());
}
}
How could I get the Notification Title of the notification ?
Here's my code :
-From Notification Service :
resultIntent= new Intent(NotificationService.this, StartNAFromNS.class);
resultIntent.putExtra(Intent.EXTRA_TITLE, underestood_name.replace("__", " "));
-From StartNAFromNS :
String text = this.getIntent().getStringExtra(Intent.EXTRA_TITLE);
When doing this with only 1 notification, I get the correct title. However, if my application sends 2 notifications, I will get the title of the second notification.
How could I get the proper notification title ?
By extending NotificationListenerService and using its onNotificationPosted method in our class we will be able to get notification title, text and package name. Using notification package we get its app icon, app name and many more.
public class MyNotification extends NotificationListenerService {
Context context;
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
// We can read notification while posted.
for (StatusBarNotification sbm : MyNotification.this.getActiveNotifications()) {
String title = sbm.getNotification().extras.getString("android.title");
String text = sbm.getNotification().extras.getString("android.text");
String package_name = sbm.getPackageName();
Log.v("Notification title is:", title);
Log.v("Notification text is:", text);
Log.v("Notification Package Name is:", package_name);
}
}
}
Notification id should be unique within your application.
If a notification with the same id has already been posted by your
application and has not yet been canceled, it will be replaced by the
updated information.
NotificationManager notiManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(UNIQUE_ID, notification);
If you are using PendingIntent.getActivity() method, use different requestCode for different notification:
Intent resultIntent= new Intent(NotificationService.this, StartNAFromNS.class);
resultIntent.putExtra(Intent.EXTRA_TITLE, underestood_name.replace("__", " "));
PendingIntent pI = PendingIntent.getActivity(mContext, REQUEST_CODE, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Hope this will help!
This code properly working for the fcm. We can send a message and title from the fcm console or server. The notification received by the registered mobile app.
#Override
public void onMessageReceived (String from, Bundle data) {
//Getting the message from the bundle
long dateTime = data.getLong("google.sent_time");
Bundle notificationBundle = data.getBundle("notification");
String message = notificationBundle.getString("body");
String title = notificationBundle.getString("title");
//Displaying a notiffication with the message
sendNotification(title, message);
}
//The following method is generating a notification and displaying the notification
private void sendNotification(String title, String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", message);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= 21)
noBuilder.setSmallIcon(R.mipmap.ic_launcher);
else
noBuilder.setSmallIcon(R.mipmap.ic_launcher_small);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
This class won't to handle multiple GCM messages and show them on notification bar,currently handle only one, how can make it to handle multiple messages?
public class GCMIntentService extends GcmListenerService {
private static final String TAG = "GCMIntentService";
int notifyid = 0;
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "from:" + from);
Log.d(TAG, "message:" + message);
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, notifyid, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo)
.setContentTitle("New Messsage")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSound)
.setContentIntent(pendingIntent);
int numMessages = 0;
notificationBuilder.setContentText(message).setNumber(++numMessages);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifyid, notificationBuilder.build());
}
}
}
From the documentation:
public void notify (int id, Notification notification)
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
notifyid never appears to change in the code you've posted, which is why you only see a single notification.
I want to cancel/delete the notification after I click the addAction.
However it's not working. The notification is still there after the click.
I'm pretty sure this worked in an other project.
Can anyone see a stupid error I made, why its not working?
Actual code:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
showNotification(context);
}
private void showNotification(Context context){
String onderwerp = ("Medicatietijd");
String name = ("Het is tijd om je medicitie in te nemen.");
// Geluid notificatie
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, Test.class), 0);
// De notificatie
Notification mNotification = new Notification.Builder(context)
.setContentTitle(onderwerp)
.setContentText(name)
.setSmallIcon(R.drawable.ninja)
.setSound(soundUri)
.addAction(R.drawable.ja, "Ja, ik heb ze ingenomen.", contentIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager
= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotification.vibrate = new long[]{100, 200, 100, 500};
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, mNotification);
}
Solution:
In test activity OnCreate added this:
NotificationManager notificationManager
= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(0);
If you decided to use Test activity to receive the intent of your addAction call, then you must cancel notification when you receive the intent in the activity.
I also recommend that you add requestCode for the intent.
Here is the code :
to set the requestCode modify this :
static final int REQ_CODE = 101; // some number
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, REQ_CODE,
new Intent(context, Test.class), 0);
to Handle intent in activity and dismiss the notification, in Test activity class :
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CODE) {
// dismiss notification
notificationManager.cancel(0);
// handle your action
// ...
}
}
Hope that helps