I stuck in a problem.
Suppose there is an activity A
now, user press Home key, and put A into background.
now, after remaining in background for a while, it will generate a notification.
On clicking on that notification, it will bring back the exact same activity which was in the background.
Like, after pressing home key, if user start the application again by clicking on the icon or from the recent launched history, then android re-opens exactly last activity in it's previous state.
Here, I dont want to detect which was the last activity. My activity is fixed, I just want to bring it back at its previous state on clicking on the notification ?
Is that possible ? how to do that ?
here is my code for notification,
private void generateNotification(Context context, String message, String data) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.notification, message, System.currentTimeMillis());
Intent notificationIntent = new Intent(context, MenuActivity.class);
//notificationIntent.setFlags(Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
Bundle bundle = new Bundle();
bundle.putString("data",data);
notificationIntent.putExtras(bundle);
//Constants.NOTIFICATION_ID++;
notification.setLatestEventInfo(context, context.getString(R.string.app_name), message, PendingIntent.getActivity(context, 0, notificationIntent, Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR));
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(Constants.NOTIFICATION_ID, notification);
}
Use Intent.FLAG_ACTIVITY_CLEAR_TOP instead of FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY.
Related
I have implemented smooch. https://smooch.io/
And my issue is that when I get the notification from smooch. If I'm in the background, I set a "unread messages" long that I use in my main activity on the smooch button.
The issue is that when I press on the notification, and the ConversationActivity is started from there. I need to set the unread messages to 0, because the ConversationActivity is opened. How can I know when this happens?
I cannot modify ConversationActivity.class from the smooch library.
I thought about making the notification myself, and changing the smooch created one with this one using this code:
private static void generateNotificationSmooch(final Context context, String title, String message) {
if (title == null)
title = context.getString(R.string.passenger_name);
Intent notificationIntent = new Intent(context, ConversationActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
PendingIntent intent = PendingIntent.getActivity(context, iUniqueId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle(title).setContentText(message).setSmallIcon(R.drawable.notification_icon);
mBuilder.setContentIntent(intent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
But I need to set the unread to 0 when the notification is pressed, and not when I create the notification. And I can't put it in pending intent
You have a few options.
Use the onSmoochShown delegate callback.
This callback will be triggered when the conversation is shown, so you will be able to update your unread count.
Use the onUnreadCountChanged delegate callback
.
This delegate will be called whenever the unread count changes for current user. You can use this callback to update your long accordingly.
Since you will need to be listening to these delegate callbacks when a notification is tapped, it may be best to set your delegate in your Application’s onCreate, after you initialize Smooch.
There are 3 cases in Push Notification.
Case 1 : App is already running and notification appears.
Case 2 : App is closed and notification appears but app is opened by clicking app icon
Case 3 : App is closed and app is opened from notification click
My question is how to detect whether app is opened from case 2 or case 3? If I able to detect than I can save some value in preference and using that value I can differentiate whether I have to open Main Activity or Notification Activity.
If you have better idea to decide which activity should be opened after splash (either Main Activity or Notification Activity) than Kindly tell me.
Notification notification = new Notification.Builder(context)
.setAutoCancel(true)
.setContentTitle("My Notification")
.setContentText("You have a received notification.")
.setSmallIcon(getNotificationIcon())
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
R.drawable.ic_launcher))
.build();
notification.defaults=Notification.DEFAULT_SOUND;
notification.number = notificationCount++;
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.putExtra("pushClicked", true);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
System.out.println("title="+title+"message="+message);
notification.setLatestEventInfo(context, title, message, contentIntent);
int SERVER_DATA_RECEIVED = 1;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(SERVER_DATA_RECEIVED, notification);
In the Target(Splash) activity
boolean pushClicked = false;
if(getIntent()!=null){
pushClicked = getIntent().getStringExtra("pushClicked");
System.out.println("pushClicked="+pushClicked);
}
System.out.println(pushClicked );
Always getting false
Add an extra boolean value along with the intent created to open up application activity inside notification receiver.
For example :
#Override
public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
Intent splashIntent = new Intent(context, TargetActivity.class);
splashIntent.putExtra("pushClicked", true);
context.startActivity(splashIntent);
}
Check for this boolean value inside the TargetActivity to distinguish between push click and app icon click.
Is it possible not launch new activity if we receive a push notification while the app is running?
My activity works with fragments and I want to do transition to a determinate fragment when the notification is received. My activity have data that I need to show the fragments. The problem is that when I receive the push notification while the app is running the method onDestroy is called and here I clear the data and then the app crash because the data are null. How can I do to not create new activity when the app receive a push notification while is running? In case the app is running I want that if you click the notification do a transition fragment, not create again the activity.
Thanks in advance.
First of all, I think that you mean "notification" to be a "message", but not android.app.Notification class.
And second, I don't think it's a best practise to raise new GUI when receiving a message, which would interrupt the user interaction. For details, please refer to: http://developer.android.com/training/notify-user/index.html and http://developer.android.com/design/patterns/notifications.html.
At last, if you really wanna do what you stated in your thread, I wonder why the data used to generate the show-data fragment is held in the activity. Try holding the data in an android.app.IntentService object, and then generate transfer the data to new activity, and then use android.app.Fragment.setArguments method to transfer the data from activity to fragment.
I think that this code will help you. This which you need is PendingIntent, it make transaction to desired activity.
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void generateNotification(Context context, String title,
String message) {
//get the default notification sound URI
Uri uriNotificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//make intent to the application. if the application is opened just maximize it.
Intent homeIntent = new Intent(context, 'your desired activity');
homeIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
homeIntent, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("eCommCongress")
.setContentText(message)
.setLights(Color.GREEN, 1500, 1500)
.setSound(uriNotificationSound)
.setAutoCancel(true)
.setContentIntent(contentIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(counter, mBuilder.build());
counter++;
}
It is perfectly possible and I do such a thing in one of my apps. First, you need to declare your activity as android:launchMode="singleTop",
Then, when you build you must configure your pending intent not to fire a new instance of your activity:
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent("YOUR ACTION HERE");
intent.setClassName(this, MainActivity.class.getName());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.defaults |= Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS;
notification.flags |= Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(idNotificacion,notification);
Now all you have to do is to override your onNewIntent inside your Activity and do whatever you want with your fragment:
#Override
protected void onNewIntent(Intent intent) {
MiLog.i(getApplicationContext(),"IntentShit","new intent received");
MiLog.i(getApplicationContext(),"IntentShit","Action: "+intent.getAction());
if(intent.getAction()!=null && intent.getAction().equals("YOUR ACTION HERE"){
//DO your stuff here
}
}
You should also take a look at this page for more info:
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
Is it possible to use startActivityForResult() from a status bar notification?
Say I have an activity A, which on some event starts activity B using startActivityForResult(). Now when it is in the background, on the event it shows a notification. Now on selecting the notification, how do i start activity B for result?
I do realize that activity A should have a service that runs in the background, but i guess the same question would apply even in that case.
Here's the code for the notification. This is in the Activity A.
Notification notification = new Notification(R.drawable.ic_launcher, "New Notification", System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL;
CharSequence contentTitle = "My Notification Title";
CharSequence contentText = "My Notification Text";
Intent notificationIntent = new Intent(this, ActivityB.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(), contentTitle, contentText, contentIntent);
nm.notify(1, notification); //1 = id
I think that you should just start the activity A from the activity B when the activity B is opened by opening the notification and then closed.
You can pass the return value in the intent that you use to start the activity A from the activity B.
Dont use startActivityForResult. You can achieve the same functionality in different way.
Pass the result as an extra with your notification. Get this result in onResume of activity B.
I have 3 Activities
A. MainActivity - just an Activity with a text and button on it
B. SettingsActivity - this will be displayed if the button on (A) is clicked, this initializes time picker that will send a notification when it alarms
C. DisplayNotification - activity for displaying notification in the status bar, when clicked, it should show A
This is what I want to happen:
I launch my application, A will be shown
I click the button, B will be shown
I set a time for the alarm
When the alarm triggers, a notification is shown in the status bar
If I click the notification, A will be shown
This is what happens (I have 2 scenarios with different results):
First scenario:
After step 3, I tap the back button, A will now be shown
Then, I tap again the back button, the onDestroy of A will be called and screen will show the 'home page' or 'desktop' of the phone
I wait till the alarm triggers
When the alarm triggers, notification is shown on the status bar
I click the notification, it launches my app displaying A
End of story. This is what is expected to happen
Second scenario: (the buggy one)
After step 3, I tap the HOME button, A's onDestroy is not yet called and the latest screen was B
The screen shows the 'home page' or 'desktop' of the phone
I wait till the alarm triggers
When the alarm triggers, notification is shown on the status bar AND B was shown automatically without me clicking the notification on the status bar
What I want to happen here is that it should not automatically display B activity.
Am I missing any flags for notification or intent?
Here is the code snippet for Activity B which triggers the alarm
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, DisplayNotification.class);
i.putExtra("NotifID", 1);
PendingIntent displayIntent = PendingIntent.getActivity(getBaseContext(), 0, i, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, displayIntent);
Here is the code for Activity C
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int notifID = getIntent().getExtras().getInt("NotifID");
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("NotifID", notifID);
PendingIntent detailsIntent = PendingIntent.getActivity(this, 0, i, 0);
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notif = new Notification(R.drawable.ic_launcher, "See activity!", System.currentTimeMillis());
notif.flags |= Notification.FLAG_AUTO_CANCEL;
notif.defaults |= Notification.DEFAULT_SOUND;
CharSequence from = "Notification from me";
CharSequence message = "See activity!";
notif.setLatestEventInfo(this, from, message, detailsIntent);
nm.notify(notifID, notif);
finish();
}
I hope someone would help me :)
Thanks!
Edit:
Thanks Chirag_CID! I should have used Broadcast Receiver instead of another Activity. So, instead of extending Activity, the DisplayNotification now extends Broadcast Receiver. This is the onReceive method of DisplayNotification:
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "DisplayNotification onReceive");
int notifID = intent.getExtras().getInt("NotifID");
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
i.putExtra("NotifID", notifID);
PendingIntent detailsIntent = PendingIntent.getActivity(context, 0, i, 0);
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notif = new Notification(R.drawable.ic_launcher, "See the quote of the day!", System.currentTimeMillis());
notif.flags |= Notification.FLAG_AUTO_CANCEL;
notif.defaults |= Notification.DEFAULT_SOUND;
CharSequence from = "Notification";
CharSequence message = "See the activity!";
notif.setLatestEventInfo(context, from, message, detailsIntent);
nm.notify(notifID, notif);
}
I read the whole Question 2-3 times..
Now I want to point to few things up there,
You have made Activity C in which you are creating notification which will call MainActivity on it's Click.
But, When you set alarm from B you are passing intent of Activity C, Though your code of C doesn't have setContentView method, and Also you have written finish() in the end of onCreate() so when Activity C is called through the Alarm set from B, It just call Activity C and set Notification ..but As you written finish() it ends Activity C and shows Activity B latest from the Stack.
If You want to cross check..
Write logs in onCreate(),onPause() and onDestroy() of Activity C..and you will see the Activity C is created and Destroyed when Alarm triggered.
Solution:
If you don't want to show any activity when you are on Home Screen and Alarm trigger then,
In Activity B where you written pending intent for Activity C..You will need it to change to call the Broadcast Receiver and use PendingIntent.getBroadcast where its PendingIntent.getActivity and the code you have written in C for notification you will have to write that in Receiver...hence none of your activity will be called when the Alarm Trigger.
Happy Coding :)