I want to open a fragment when the app receive a notification for further processing. In my MainActivity.java, getIntent().getExtras() always return null.
MyFirebaseMessagingService.java
private void sendNotification(String title, String messageBody, String newsID, String newsType) {
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);
Bundle extras = new Bundle();
extras.putString("newsID", String.valueOf(newsID));
extras.putString("newsType", String.valueOf(newsType));
intent.putExtras(extras);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
MainActivity.java
Bundle i = getIntent().getExtras();
if (i != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.e("News ID", value);
if (key.equals("newsID") ) {
dbHelper.insertNewsID(String.valueOf(value));
//show news details
getSupportFragmentManager()
.beginTransaction()
.replace(ng.naijaleague.R.id.frame_container, new NewsDetails())
.addToBackStack(null).commit();
}
}
String newsType = getIntent().getExtras().getString("newsType");
if ("newsType".equals(newsType) ) {
String value = getIntent().getExtras().getString("newsType");
if("Local".equals(value)){
//add news type to shared preference
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("newType", "Local");
editor.apply();
}else{
//add news type to shared preference
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("newType", "Foreign");
editor.apply();
}
}
}
I have followed through all the solutions I found on SO but none of them have worked so far. What must be wrong with the code?
POST THIS 4 lines before making PendingIntent Object :P
Bundle extras = new Bundle();
extras.putString("newsID", String.valueOf(newsID));
extras.putString("newsType", String.valueOf(newsType));
intent.putExtras(extras);
LIKE:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//PUT HERE
Bundle extras = new Bundle();
extras.putString("newsID", String.valueOf(newsID));
extras.putString("newsType", String.valueOf(newsType));
intent.putExtras(extras);
//THEN Create PendingIntent Object
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Hope it will helps you :)
Thanks to everyone, all the answers moved me closer to making it work but I needed to change the PendingIntent to the following to nail it.
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Thanks...<3
move extras assign before Pending intent is created
add flag:
FLAG_ACTIVITY_NEW_TASK
Note than when using PendingIntent.getActivity(...) the activity will be started outside of the context of an existing activity, so you must use the Intent.FLAG_ACTIVITY_NEW_TASK launch flag in the Intent.
Related
I want to update the content for a reminder after it has been added before being received by the user. After setting a reminder through AlarmManager using the data stored in sqlite database, the notification from the reminder set only shows the data, title and description, that was first added, not any updated data stored corresponding to the ID as primary key.
Things I have tried:
cancelling the pending intent for the reminder then setting it again after updating the data stored in the database but it still displays the same result.
using an activity for adding data to be stored in the database to set a reminder and using another activity for updating this data as an attempt to update the reminder content with the same ID issued. One result shows two notifications received, one with initial title and description, and the other with updated information.
Currently, the methods I use to set and cancel a reminder is in my Adapter class for Recyclerview. I am stuck on updating although adding and cancel works fine.
Update: Now I use two separate activities for the add and update reminder functions.
For adding a reminder:
databaseManager.addReminder(titlePicked, descriptionPicked, timePicked, datePicked, dateTimePicked);
startActivity(new Intent(getApplicationContext(), MainActivity.class));
setAlarm();
private void setAlarm() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), ReminderReceiver.class);
intent.putExtra("DateTime", dateTimePicked);
intent.putExtra("NotifID", remId);
intent.putExtra("Title", titlePicked);
intent.putExtra("Description", descriptionPicked);
PendingIntent addIntent = PendingIntent.getBroadcast(this, remId, intent, 0);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, Date.parse(dateTimePicked), addIntent);
}
For updating a reminder:
databaseManager.updateReminder(remindId, titlePicked2, descriptionPicked2, timePicked, datePicked, dateTimePicked);
startActivity(new Intent(getApplicationContext(), MainActivity.class));
updateAlarm();
private void updateAlarm() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), ReminderReceiver.class);
intent.putExtra("DateTime", dateTimePicked);
intent.putExtra("NotifID", remindId);
intent.putExtra("Title", titlePicked2);
intent.putExtra("Description", descriptionPicked2);
PendingIntent updateIntent = PendingIntent.getBroadcast(this, remindId, intent, 0);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, Date.parse(dateTimePicked), updateIntent);
}
Receiver class:
public class ReminderReceiver extends BroadcastReceiver {
private static final String CHANNEL_ID = "CHANNEL_REMIND";
String DateTimeChoice, TitleChoice, DescriptionChoice;
int notificationID;
#Override
public void onReceive(Context context, Intent intent) {
DateTimeChoice = intent.getStringExtra("DateTime");
notificationID = intent.getIntExtra("NotifID", 0);
TitleChoice = intent.getStringExtra("Title");
DescriptionChoice = intent.getStringExtra("Description");
Intent mainIntent = new Intent(context, ViewReminder.class);
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, notificationID, mainIntent, 0);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// For API 26 and above
CharSequence channelName = "My Notification";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle(TitleChoice)
.setContentText(DescriptionChoice)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setColor(context.getResources().getColor(R.color.purple_700))
.setAutoCancel(true);
notificationManager.notify(notificationID, builder.build());
}
Adapter class:
int remindId = reminder.getReminderId();
databaseManager = new DatabaseManager(holder.view.getContext());
sqLiteDB = databaseManager.getWritableDatabase();
public void onClick(View view) {
Reminder reminder = remindList.get(holder.getAdapterPosition());
PopupMenu popupMenu = new PopupMenu(view.getContext(), view);
popupMenu.setGravity(Gravity.END);
popupMenu.getMenu().add("Edit").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Intent intent = new Intent(view.getContext(), UpdateReminderActivity.class);
intent.putExtra("reminderId", remindId);
intent.putExtra("title", reminder.getReminderTitle());
intent.putExtra("definition", reminder.getReminderDefinition());
view.getContext().startActivity(intent);
return true;
}
});
For updating a pending intent, you need to use FlAG_UPDATE_CURRENT with the same id you used earlier to set the initial intent.
If you want to update the alarm associated with that pending intent, you need to cancel the old alarm & then the old PendingIntent. Then create a new PendingIntent like this,
PendingIntent updateIntent = PendingIntent.getBroadcast(this, remindId, intent,PendingIntent.FLAG_UPDATE_CURRENT);
and set it to the alarm.
I want to show a notification at some event, that's working fine, I am also landing on an activity I want but problem is that, intent data is empty, please here, Here is the code
Intent resultIntent = new Intent(context, MovieDetailActivity.class);
resultIntent.putExtra(Constants.MOVIE_ID, cursor.getString(
cursor.getColumnIndexOrThrow(DatabaseHelper.ID)));
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_download)
.setContentIntent(resultPendingIntent)
.setContentTitle(cursor.getString(
cursor.getColumnIndexOrThrow(DatabaseHelper.NAME)))
.setAutoCancel(true)
.setContentText(cursor.getString(
cursor.getColumnIndexOrThrow(DatabaseHelper.REALEASE_DATE)));
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build()
);
I am sending some data using intent, in this line.
resultIntent.putExtra(Constants.MOVIE_ID, cursor.getString(
cursor.getColumnIndexOrThrow(DatabaseHelper.ID)));
I am receiving data here but it Null.
Intent receivedIntent = getIntent();
mMovieId = receivedIntent.getIntExtra(Constants.MOVIE_ID, -1);
Please help, I have spent whole day on this.
You pass into intent String so you can't get Integer from intent, that's why you get null.
So change this line:
mMovieId = receivedIntent.getIntExtra(Constants.MOVIE_ID, -1);
to
mMovieId = receivedIntent.getStringExtra(Constants.MOVIE_ID);
// and simply parse string to integer
int id = Integer.parseInt(mMovieId);
You need change your PendingIntent for:
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0 , resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
I hope it solve your problem.
I am trying to make Notification Reply like whatsapp.
here is my code
public void sendNotification(String msg, Intent i, ContactModel contact)
{
i.putExtra("message", msg);
i.putExtra("contact", new Gson().toJson(contact));
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
String replyLabel = "Reply";
RemoteInput remoteInput = new RemoteInput.Builder("KEY_REPLY")
.setLabel(replyLabel)
.build();
PendingIntent contentIntent = PendingIntent.getActivity(context, 100, i,
PendingIntent.FLAG_UPDATE_CURRENT);
Bundle bundle = new Bundle();
bundle.putBoolean("reply", true);
NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
R.drawable.ic_phone, replyLabel, contentIntent)
.addRemoteInput(remoteInput)
.addExtras(bundle)
.setAllowGeneratedReplies(true)
.build();
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
.setContentTitle(contact.getName())
.setDefaults(Notification.DEFAULT_SOUND)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Content Hidden"))
.setContentText(msg)
.addAction(replyAction)
;
mBuilder.setContentIntent(contentIntent);
mNotificationManager.cancel(Constants.PUSH_ID);
mNotificationManager.notify(Constants.PUSH_ID, mBuilder.build());
}
Now my notification shows "Message" and a "Reply" Button.
The problem i am facing is, i can't differentiate wether user chose Reply button or tried to open the notification.
My main intent is
Intent myIntent = new Intent(this, NotificationActivity.class);
What i want is,
When a user click on "Reply" Button it opens
Intent myIntent = new Intent(this, NotificationActivity.class);
When a user click on notification itself it opens
Intent myIntent = new Intent(this, MainActivity.class);
Even if thats not possible , how can i figure out which action was performed.
Try to add
setContentIntent(new Intent(this, MainActivity.class))
Additional info here
You should create a pending intent for each case , one for reply button and another for your message notification.
addAction() define action button for your notificaion, and setContentIntent(pendingIntent) do the same for your core message.
.... your code
Intent messageIntent = new Intent(this, MainActivity.class);
PendingIntent messagePendingIntent = PendingIntent.getActivity(context, 200, messageIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
.setContentTitle(contact.getName())
.setDefaults(Notification.DEFAULT_SOUND)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Content Hidden"))
.setContentText(msg)
.setContentIntent(messagePendingIntent) // some change here
.addAction(replyAction)
Hope this helps.
Sorry for my english.
What I understand from your statement is: you are expecting two different intents for two different actions so, I'm not confirm that it will solve your problem, but this is what I tried.
public void createNotification() {
Intent intent = new Intent(this, NotificatioTest.class);
PendingIntent pIntent = PendingIntent.getActivity(this,(int) System.currentTimeMillis(), intent, 0);
Intent mIntent = new Intent(this, MainActivity.class);
PendingIntent mPIntent = PendingIntent.getActivity(this,(int)System.currentTimeMillis(),mIntent,0);
Notification noti = new Notification.Builder(this)
.setContentTitle("Your Title")
.setContentText("Your text content")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.addAction(R.drawable.ic_launcher, "Reply", mPIntent).build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
}
The change is I have used two different PendingIntent as setContentIntent(pIntent) and addAction(R.drawable.ic_launcher,"Reply",mPIentent).
Output:
https://youtu.be/vVKVMboHEOA
i trying do a "read more" after user click on notification.
What i need, start new Activity with unique extra content "id", "title" and "text".
My code:
void notificationSend(String id, String bar, String title, String text, String image, int delay) {
Bitmap bitmap = getBitmapFromURL(image, 130);
if(bitmap == null){
bitmap = getBitmapFromURL("https://pp.vk.me/c621316/v621316641/119d5/HB9s2z5mX-s.jpg", 130);
}
Intent notificationIntent = new Intent(this, SingleNewsActivity.class);
notificationIntent.putExtra("id", id);
notificationIntent.putExtra("title", title);
notificationIntent.putExtra("text", text);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(contentIntent);
builder.setSmallIcon(R.drawable.ic_bitcoin_notification);
builder.setLargeIcon(bitmap);
builder.setTicker(bar);
builder.setContentTitle(title);
builder.setContentText(text);
builder.setWhen(System.currentTimeMillis());
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
try {
notificationManager.notify(new Integer(id), notification);
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
And it do next thing, lets send 2 notifications, after i click on first, activity started but with extra data from second notification, why?
The issue is due to using : FLAG_UPDATE_CURRENT
if you see document for this flag:
Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent. For use with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int).
This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
in your case, you are updating just extra and due to that, the value of extras get updated.
For solution of your issue, you should pass request code unique for all case:
Currant code:
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Actual:
PendingIntent.getActivity(this, unique_code, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
So The reason is that you are setting unique id to the notification, lets suppose id value is 1 when your 1st notification comes then the notification object is created with that id, when you second notification come then your id is again 1 so your notification is updated and when you click on it you get the second notification.
what you can do is set the different id for notifications. have a look at below code
private NotificationManager mNotificationManager;
private NotificationCompat.Builder builder;
write below code inside a function
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Random random = new Random();
int NOTIFICATION_ID = random.nextInt(9999 - 1000) + 1000;
Intent intent = new Intent(this, SingleNewsActivity.class);
Bundle bundle = new Bundle();
bundle.putExtra("id", id);
bundle.putExtra("title", title);
bundle.putExtra("text", text);
intent.putExtras(bundle);
PendingIntent contentIntent = PendingIntent.getActivity(this, NOTIFICATION_ID,
intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("TITLE")
.setStyle(new NotificationCompat.BigTextStyle().bigText("ASD"))
.setContentText("Summary").setAutoCancel(true);
mBuilder.build().flags |= Notification.FLAG_AUTO_CANCEL;
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d("", "Notification sent suessfully.");
in the above code whenever you will receive notification you will get a unique code in NOTIFICATION_ID
I would like to put two buttons on my notifications from the status bar. Of course they do not appear until the user touches to expand them. I have created the custom layout for my notification using RemoteViews but am unsure if it's possible to obtain a reference to them because of my current code structure.
#Override
public void onMessage(Context context, Intent intent) {
Log.w("C2DMReceiver",
"Message Received, this is the message with no payload");
Bundle extras = intent.getExtras();
if (extras != null) {
String[] payload = new String[3];
payload[0] = (String) extras.get("payload");
payload[1] = (String) extras.get("payload2");
SharedPreferences sharedP = Prefs.get(this);
boolean inApp = sharedP.getBoolean("currentlyInApp", true);
if (!inApp) {
createNotification(context, payload);
}
}
}
public void createNotification(Context context, String[] payload) {
SharedPreferences sharedP = Prefs.get(context);
boolean needsToLogin = sharedP
.getBoolean("loginFromNotification", true);
Log.w("C2DMReceiver", "createNotification called");
NotificationManager notificationmanager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(this, WebViewActivity.class);
Intent notificationIntent2 = new Intent(this, UniteActivity.class);
PendingIntent pIntent;
if (needsToLogin) {
pIntent = PendingIntent.getActivity(this, 0, notificationIntent2,
PendingIntent.FLAG_CANCEL_CURRENT);
} else {
pIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
// Compatibility builder
NotificationCompat.Builder notification = new NotificationCompat.Builder(
context);
RemoteViews remote = new RemoteViews(getPackageName(),R.layout.notification);
//Button okButton = (Button) findViewById(R.layout.notification);
notification.setAutoCancel(false);
notification.setContent(remote);
notification.setContentIntent(pIntent);
notification.setWhen(System.currentTimeMillis());
notification.setTicker(payload[0]);
notification.setSmallIcon(R.drawable.default1);
notification.setContentTitle(payload[1]);
notification.setContentText(payload[0]);
long duration[] = { 100, 300, 100 };
notification.setVibrate(duration);
notificationmanager.notify(0, notification.getNotification());
}
onMessage is a method pulled from the Google C2DM library where the notifications are generated by intents received from google. Without a view, how can I obtain a reference to my buttons using findViewById()? or some other means
I think you are looking for the method:
RemoteViews.setOnClickPendingIntent(int, android.app.PendingIntent)
So, if you add...
remote.setOnClickPendingIntent(R.id.button, pIntent);
...it should work.