Android TaskStackBuilder and toolbar icon blink - android

My code of notification:
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText("test")
.setAutoCancel(true)
.setTicker("Powiadomienie: test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
Intent ia = new Intent(this, ActivityA.class);
Intent ib = new Intent(this, ActivityB.class);
Intent ic = new Intent(this, ActivityC.class);
stackBuilder.addNextIntent(ia);
stackBuilder.addNextIntent(ib);
stackBuilder.addNextIntent(ic);
mBuilder.setContentIntent(stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT));
mNotificationManager.notify(1, mBuilder.build());
Order of activity is:
ActivityA -> ActivityB -> ActivityC
When shows ActivityC stack is build from end like in code. On back button show ActivityB and ActivityA.
On video shows what's happen:
http://www.youtube.com/watch?v=YP_-KE-fuCg
When shows last activity (ActivityA) toolbar icon show standard icon and after shows icon of activity. This icon is set in AndroidManifest.xml
<activity android:name="ActivityA" android:icon="#drawable/ic_launcher2"></activity>
<activity android:parentActivityName=".ActivityA" android:name="ActivityB" android:icon="#drawable/ic_launcher2">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ActivityA" />
</activity>
<activity android:parentActivityName=".ActivityB" android:name="ActivityC" android:icon="#drawable/ic_launcher2">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ActivityB" />
</activity>
I cant find answer how to fix it. I dont want to blink icon. Someone have solution of this problem?
Here is sample code: https://dl.dropboxusercontent.com/u/6099319/NotificationTest.zip

Related

Unable to create back stack for activities

I am receiving a notification and i want to create a custom back stack so the user can navigate through it.But as of now clicking on the notification opens the desired activity but when i press the back button it completely exits the app.
Intent resultIntent = new Intent(this, NotifViewActivity.class);
resultIntent.putExtra(StringHolder.NOTIFICATION_ID, notif.getId());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(HomeActivity.class);
stackBuilder.addParentStack(NotifActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationCompat = new NotificationCompat.Builder(context)
.setAutoCancel(true)
.setContentTitle(notif.getTitle())
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(resultPendingIntent);
Manifest File
<activity
android:name=".NotifActivity"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".HomeActivity" />
</activity>
<activity
android:name=".NotifViewActivity"
android:parentActivityName=".NotifActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".NotifActivity" />
</activity>
The way i want it to work is,on click of the notification the user is taken to
NotifViewActivity then when back button is pressed the user is taken to NotifActivity and when back button is pressed again the user is taken to
HomeActivity .Thats the hierarchy i am trying to create,how can i do that?
You should build your task stack that way:
stackBuilder.addParentStack(HomeActivity.class);
stackBuilder.addParentStack(NotifActivity.class);
stackBuilder.addNextIntentWithParentStack(resultIntent);
Or actually because you already specifying activity hierarchy in manifest, you can do it with just one line:
stackBuilder.addNextIntentWithParentStack(resultIntent);
Or another way to archive the same without specifying hierarchy in manifest:
Intent mainActivityIntent = new Intent(this, HomeActivity.class);
Intent notifActivityIntent = new Intent(this, NotifActivity.class);
stackBuilder.addNextIntent(mainActivityIntent);
stackBuilder.addNextIntent(notifActivityIntent);
stackBuilder.addNextIntent(resultIntent);
For anyone who is trying to start those the created activity with TaskStackBuilder, follow #Divers solution and then use taskStackBuilder.startActivities().
try this :
put below code into NotifViewActivity
#Override
public void onBackPressed() {
Intent i = new Intent(this, HomeActivity.class);
i.putExtra("exit", true);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
super.onBackPressed();
}

Android navigation up about notification with TaskStackBuilder

I want to start the "ChatActivity" of my app by click Notification, and when i click back button, we will go to the "MainActivity" of my app. I write my code as the Android Notification Guide. My code is follow.
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_MESSAGE)
.setContentTitle("你有" + unreadCount + "条新的消息")
.setContentText(content)
.setNumber((int) unreadCount)
//.setColor(Color.RED)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.mipmap.icon_notify_bold);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
Intent resultIntent = new Intent(context, ChatActivity.class);
resultIntent.putExtra("to", CommonUtils.removeString(conversation.communicator,
ProfileHelper.getProfile().username));
resultIntent.putExtra("conversationId", conversation.id);
taskStackBuilder.addParentStack(ChatActivity.class);
taskStackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = taskStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
manager.notify(NOTIFY_ID_MESSAGE, builder.build());
My manifest xml is like this:
<activity
android:name=".ui.HomeActivity"
android:label="#string/homepage"
android:launchMode="singleTask"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".ui.ChatActivity"
android:label="#string/back"
android:launchMode="singleTask"
android:parentActivityName=".ui.HomeActivity"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.HomeActivity" />
</activity>
My problem is when I press back button in ChatActivity, the HomeActivity will be recreated even if I already started my app. If I have started my app and stay at the HomeActivity page, I think it should not created again. How to avoid recreate HomeActivity?
Any help is grateful.
On ChatActivity class add the following code snippet
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}

Get back to previous Activity when Ongoing notification is clicked

I'm having an activity with some EditTexts and an Ongoing Notification.
After filling into EditTexts, I come back Home screen by pressing Home button (my app is running in background). All I want is to come back my activity with filled EditTexts (not to create a new one) when I click the Ongoing Notification.
I have tried this
How should i do from notification back to activity without new intent
And this
Notification click: activity already open
They don't work at all !!!
Below is my code snippet
ProtocolMonitorActivity.java
Intent resultIntent = new Intent(this, ProtocolMonitorActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ProtocolMonitorActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Protocol Monitor App")
.setContentText("Service is running")
.setOngoing(true);
notiBuilder.setContentIntent(resultPendingIntent);
notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(notiId, notiBuilder.build());
Manifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ProtocolMonitorActivity"
android:label="#string/app_name"
android:process="com.android.phone"
android:launchMode="singleTop"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ProtocolMonitorActivity" />
</activity>
</application>
Does someone have any idea on this?
Thank you so so much!!!
You cannot do this using TaskStackBuilder. The behaviour of TaskStackBuilder is that it always clears the task (recreating any activites).
You just need a "launch Intent" to bring your task to the foreground in whatever state it happens to be in. There's 2 ways to do this:
Varient 1:
final Intent notificationIntent = new Intent(this, ProtocolMonitorActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Variant 2:
final Intent notificationIntent =
PackageManager.getLaunchIntentForPackage(getPackageName());
Then do:
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notiBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Protocol Monitor App")
.setContentText("Service is running")
.setOngoing(true);
notiBuilder.setContentIntent(resultPendingIntent);
notiManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notiManager.notify(notiId, notiBuilder.build());
Just insert this line
resultIntent.setAction(Intent.ACTION_MAIN);
set android:launchMode="singleTop" in your activity tag in menifest inside required activity.

Open Application home page after dismissing notification

Upon pressing the back button, after opening the notification, the user is taken back to the Home screen instead of going back to the main page of the application. (Using a Samsung S5 with Android 5.0)
The notification is built and shown as follows:
NotificationManager mNotifyMgr =
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(GcmMessageHandler.this, ListViewItemDetailActivity.class);
Bundle b = new Bundle();
//... put some data
resultIntent.putExtras(b);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(GcmMessageHandler.this);
stackBuilder.addParentStack(ListViewItemDetailActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(GcmMessageHandler.this)
.setContentTitle("Notification")
.setSmallIcon(R.drawable.common_signin_btn_icon_dark)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setContentIntent(resultPendingIntent)
.setPriority(0)
.setContentText(title);
mNotifyMgr.notify(mNotificationId++, mBuilder.build());
Also in the Manifest file, i have set the parentActivity as follows
<activity
android:name=".ListViewItemDetailActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
The simplest thing that you can do is pass the bool variable form your notification e.g**(_Is_Coming_From_notification)** and in your ListViewItemDetailActivity activtiy get that variable and based on that if user go back open your app home page.
below is some code for your reference.
resultIntent.putExtra("is_Comming_Form_Notification", true);
get that in your activity.
boolean _Is_Comming_From_Notification = intent.getBooleanExtra("is_Comming_Form_Notification", false);
and in your BackPressed method
#Override
public void onBackPressed() {
if (_Is_Comming_From_Notification ) {
Intent intent = new Intent(this, App_Home_Page.class);
startActivity(intent);
}
super.onBackPressed();
}

start second activity and fail to back to first activity

Assume that I completely quite my application. (no more activity stack)
However, the notification arrive and user will be navigate to second activity when click
The question is how can I make an second activity back to first activity (lancher) and then exit
instead of exit directly if press back button (because it doesn't have any stack)!?
NOTIFICATION WHICH NAVIGATE TO SECOND ACT.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_social_person)
.setContentTitle("AIR° TRACKING MODE!")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setLights(Color.BLUE, 500, 500)
.setDefaults(Notification.DEFAULT_ALL)
.setOngoing(true);
PendingIntent contentIntent = PendingIntent.getActivity(
this,
0,
new Intent(this, Activity_Second.class).addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT),
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(GM.NOTIFICATION_TRACKING_MODE, mBuilder.build());
}
TaskStackBuilder is the best choice, I think so...
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(Activity_One.class);
stackBuilder.addNextIntent(resultIntent);
and in the Manifest:
work for API < 16
<activity android:name=".Activity_Second">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".Activity_One" />
</activity>
for API > 16
<activity android:name=".Activity_Second"
android:parentActivityName=".Activity_One" />
sorry. when use TaskStackBuilder, remember to edit you PendingIntent like this:
PendingIntent contentIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
Try this..
You can add that in onBackPressed() Override method from Activity_Second.class to Activity_First.class
#Override
public void onBackPressed() {
Intent ide = new Intent(this, Activity_First.class);
ide.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(ide);
finish();
}
Use TaskStackBuilder:
Read this document.
Use this code
#Override
public void onBackPressed() {
Intent ide = new Intent(this, Activity_First.class);
ide.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(ide);
finish();
}
TaskStackBuilder is the most appropriate for complex activity
Easy to manage... if you know how !
Navigate Code from Notification & add proper back stack
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_social_person)
.setContentTitle("AIR° TRACKING MODE!")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setLights(Color.BLUE, 500, 500)
.setDefaults(Notification.DEFAULT_ALL)
.setOngoing(true);
PendingIntent contentIntent = TaskStackBuilder.create(this)
//addParentStack is destination class not its parent class
//it will refer parent class from what you define in XML
.addParentStack(Activity_TrackingMode.class)
//and provide intent for destination class
.addNextIntent(new Intent(this, Activity_TrackingMode.class))
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(GM.NOTIFICATION_TRACKING_MODE, mBuilder.build());
Example of XML in AndroidManifest
<activity android:name=".Activity_TrackingMode"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:parentActivityName=".Activity_Screen1">
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".Activity_Screen1" />
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
PS. > import android.support.v4.app.TaskStackBuilder; //for support API below 16

Categories

Resources