strange behavior when starting activity from notification - android

I am using Parse to send notification to Android phones and when I receive push I will generate a notification using the below function.
private void generateNotification(Context context, String title, Intent intent, boolean hasSound) {
int NOTIFICATION_ID = ("onccent" + System.currentTimeMillis()).hashCode();
PendingIntent contentIntent = PendingIntent.getActivity(context, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotifM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher).setContentTitle(context.getString(R.string.app_name)).setContentText(title);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
if (!hasSound) {
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
}
mNotifM.notify(NOTIFICATION_ID, mBuilder.build());
}
The intent is a intent of a activity displaying messages and let's call it Activity B. I will use Activity A to represent the home activity.
The problem is: when A exists, all things work well. When I click a notification, the stack becomes
A -> B1
And click another:
A -> B1 -> B2
This is what I expect. However, when I kill the whole app and then click on the first notification. It will open a B but the following notification will only bring my app to front without open a new B.
It seems something will not work without A. I manage to open A first if A does not exist in the stack so that define A as the parent activity of B. The notification works but it seems all previous activity goes away.
How can I solve this? In short, I just want that a new activity will open when I click on the notification.

Related

FireBase-Prevent relaunching app after pressing back btn at the activity called by onMessageReceived

From the MainAcitivty I call the
startActivityForResult(new Intent(this, ActivityB.class), Constant.something);
My Application is on foreground with the ActivityB and my device receive the firebase's notification. The onMessageReceived is called
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getNotification() != null) {
openNewActivity(remoteMessage.getNotification().getBody());
}
}
private void openNewActivity(String messageBody) {
Intent resultIntent = new Intent(this, ActivityC.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
bundle.putString(NotificationViewActivity.MESSAGE_EXTRA, messageBody);
resultIntent.putExtras(bundle);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , resultIntent,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.icon)
.setContentTitle("TESTTTTT")
.setContentText(messageBody)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager ) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1000, builder.build());
}
When I click the firebase's notification when my app is on foreground, the activityC appears. However, when I press back button on my device, it returns to the MainActivity instead of returning the ActivtyB. Therefore, the app calls the onCreate of the MainActivity, it seems relaunch my app. Is there any way to prevent it, I want when press back button, the app returns the the MainActivty (want it calls the onStart-> onResume instead of onCreate->onStart->onResume of MainActivity)
However, when I create the new project with the simple activities. It happened like I want but in my project I is not right. Sorry for my language
Sorry, above code is right. My teammate put the wrong code at the onBackPressed in activityC. That code calls the MainActivity and set the intent's flags are android.intent.action.MAIN and android.intent.category.LAUNCHER. It makes the app running wrong like I described above

Current Activity finished when I build a notification

I want to start a notification in current Activity (ChatActivity),when I touch the notification ,I want to enter the ChatOneActivity.
However I don't want the current Activity (ChatActivity) finished when I'm in the ChatOneActivity(Because I'm receiving the data).And when I press the back button,I want to stay in the ChatActivity.
(The point is I do not want the ChatActivity finish ,no matter which activity I am current in).
So what should I do?
Here is the code
private void showNotification(String id, String message) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(android.R.drawable.sym_action_email)
.setContentTitle("You have a new message")
.setContentText(message);
Intent intent = new Intent(ChatActivity.this,ChatOneActivity.class);
intent.putExtra("toId", id);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(ChatActivity.this);
stackBuilder.addParentStack(ChatOneActivity.class);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, builder.build());
}
Now I enter the ChatOneActivity,when I press the back button,I return to the desktop. means that the ChatActivity has already finished,which I don't want
I believe you can't do what you want.
First of all, take a look to this link https://developer.android.com/guide/components/tasks-and-back-stack.html worth a read.
You are opening ChatOneActivity from ChatActivity and it will be saved in the Back Stack, Android system can kill your activity when memory is needed but it will be recreated.
Also, you are adding ChatOneActivity as a parent in the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(ChatActivity.this);
stackBuilder.addParentStack(ChatOneActivity.class);
If you are in the parent activity and the back button is pressed, is reasonable that the app will close.
If you want to open Activity2 from Activity1 and when you press back return to the Activity1 you shouldn't have to do anything, the Android Back Stack will manage the behavior.

Catch two notifications in android

I am creating notifications with following code:
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle(messageBody)
.setAutoCancel(true)
.setSmallIcon(R.drawable.top_icon)
.setContentText(senderName)
.setTicker(senderName+" ")
.setSound(soundUri);
Intent resultIntent = new Intent(this, LoginActivity.class);
resultIntent.putExtra("gcm_username",senderName);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_ONE_SHOT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NotificationID.getID(senderName), mBuilder.build());
When user clicks the notification I am catching it with following code in loginActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
gcmUserId= getIntent().getStringExtra("gcm_username");
startAction(gcmUserId);
....
My problem starts here.
Scenario:
1)When app is closed user receives notifications from 2 different users
2)User clicks first notification and app starts then startAction method calls.
3)Then user clicks the second notification
But when user clicks the second notification app has already started so startAction won't be able to call again because it is in the onCreate method.How can catch second notification ?
You can handle it inside onNewIntent(). You would need to override that method inside your activity. The docs say:
This is called for activities that set launchMode to "singleTop" in their package, or if a client used the FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent). In either case, when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

Replace current top activity from intent

In my Android app I send Notification like that:
Intent intent = new Intent(ctx, MyActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(ctx, myActivityId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
int icon = R.drawable.ic_launcher;
Notification n = new Notification.Builder(ctx)
.setContentTitle(messageTitle)
.setContentText(messageSubtitle)
.setSmallIcon(icon)
.setContentIntent(pIntent)
.setAutoCancel(true).getNotification();
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(myActivityId, n);
Now when I tap on notification I go to MyActivity activity. I usualy send couple notification at once. When I tap on first notification and then immediately tap on second notification I will have 2 views in my views stack. I mean when I tap back on my phone from second notification activity I'm back to first notification activity. I want to second notification activity replace first notifitaction activity that when I tap back I go to view which was displayed before I started taping on notifications. How can I do that?

Preserve back activity while clicking notification

My problem is like that: When I'm pressing the notification i got, some activity is open, lets say activity number 3. But when I press the back button, I navigated by the android to the menu. What I want to do is to preserve the correct navigation experience of the user, and when I'm pressing the back button it will take me to activity number 2, and when I'm pressing there on the back button, it will take me to activity number 1, and so on.
Another problem I have is that, when I'm opening activity number 2, I need to set there some extra data in the intent, but I don't know how to set it.
Summery of my problem: preserve the correct navigation of the user and set some extras for the activity that will be open by the back button click.
Here is my notification code:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("New Question")
.setContentText("" + CurrentQuestion.getAuthor().getUserName() + ": " + CurrentQuestion.getQuestion() + "");
Intent openHomePageActivity = new Intent("com.example.ihelp.HOMEPAGEACTIVITY");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(openHomePageActivity);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
Thanks!
Looks like you want to synthesize a back stack: http://developer.android.com/training/implementing-navigation/temporal.html#SynthesizeBackStack (see "Create back stack when starting the activity")
and also http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse ("Preserving Navigation when Starting an Activity" as a "Regular activity")
Anyone in same scenario can use this solution that I use in my apps.
Override onBackPressed (in your activity routed from notification) and check if your app is in stack or not. if not then start your root activity. User can always navigate from your root activity. This is what I do in my apps
#Override
public void onBackPressed() {
if (isTaskRoot()) {
Intent intent = new Intent(this,YourMainActivity.class);
startActivity(intent);
super.onBackPressed();
}else {
super.onBackPressed();
}
}
Save the parameters you need in onSaveInstanceState & get them back in onRestoreInstanceState. that way it won't matter if your activity was paused by any other notification as well.

Categories

Resources