I am experiencing a strange behavior with my android application when dealing with a notification that is created from a BroadcastReceiver when a C2DM message arrives on the mobile device. The flow I am executing to experience this behavior is the following one:
Start my application, DashboardActivity is displayed;
Close application either by pressing home button or back button;
Receive the push message and create the notification;
Click the notification item and the activity BookingOfferActivity is launched;
Close the BookingOfferActivity either by pressing home or back button or calling finish()
Long press home button and select my application from recent applications
BookingOffcerActivity is displayed instead of DashboardActivity
The BookingOfferActivity is being launched from the notification using the following code:
Intent notificationIntent = new Intent(context, BookingOfferActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle b = new Bundle();
b.putSerializable("booking", booking);
notificationIntent.putExtras(b);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate;
notification.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(AppUtil.getNextPushIndexBooking(), notification);
BookingOfferActivity is defined in the AndroidManifest this way:
<activity android:name=".activity.BookingOfferActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" />
and my DashboardActivity is defined like this:
<activity android:name=".activity.DashboardActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="stateHidden|adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The reason I am calling it a strange behavior is that I would like to start DashboardActivity whenever my application is started or restarted by the user, not by the notification item. So after closing, finishing or destroying BookingOfferActivity and reopening by application by accessing recent opened application (long press on home button) or accessing the launcher icon on the application list, I would like to see the Dashboard.
I create a question similar to this one but I didnt provide too much details, so I closed the other one and opened this one with more data.
Many thanks for any guidance on how to solve this problem
T
I'm not sure, but I suppose that in your scenario second activity just go to the top of activity stack and will be shown until application wont be killed. We have approximately same problem and solv it in easy way: Notification start main(first) activity with extra "go to second immediately". in onCreate of first activity check this extra and start second activity if needed. With this solution you should be careful with pressing back button - if you dont want to show first activity in case of "notification start" you should care about it in onResume of first activity
Related
I want to create a constant notification on status bar (like current battery percents - it's always there), but the icon will be changed every day on 00:00.
In addition, I want this notification will alert automatically after rebooting the device and not only after the user opens the application.
I created the notification in MainActivity, but I don't know how to make it alert after rebooting and also I don't know how to change it every day at mid-night.
I tried to create AlarmService and broadcast reciever but it run every 5 seconds and it's far too much so I deleted it.
My current code is:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.notificationTitle))
.setContentText(....)
.setLargeIcon(largeIconBitmap)
.setSmallIcon(getResources().getIdentifier("icon_status_" + myHelper.getCurrentImageNumber(),"drawable", getPackageName())); // change the icon at mid-night. 'getCurrentImageNumber' should get me the right icon number
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(mylHelper.myRequestCode, notification);
Right now I see a notification, but the icon doesn't change and it does not alarm after reboot. I saw some answers in stackoverflow but nothing helped me.
I wont give you all the code, you will need to learn by doing.
Here is what you should do:
1 Use a Service to launch your notification and maintain the logic to updating it. If the notification already exists you can update the existing one or programmatically dismiss it and replace with a new one.
2 Register a broadcast receiver in AndroidManifest.xml with multiple intent filters to launch your service.
<receiver android:name=".myReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_TICK" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
3 Create class which extends the broadcast receiver class and use and launch the above service.
I want to show a notification while a timer is running and when the user clicks the notifiaction it opens the timer activity.
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Activity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
The problem right now is that when I start the timer and press home and then click the notification it opens the Activity with the running timer.
But when I start the timer, then open another activity (via ActionBar.NAVIGATION_MODE_LIST), then press home and click the notification it opens a new Activity (empty).
I thought addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); would help (thats what I used to navigate between Activities)
im using android:launchMode="singleTop" and android:configChanges="orientation|screenSize"
for every Activity.
I wouldn't rely on your activity persisting and it is unnecessary
Store the timer start time into sharedpreferences and then simply load up the start time when the activity is recreated.
If something is meant to happen after a certain time, like a countdown time, then you'll need to set up an Alarm and handle it that way.
Remember that activities are just UI. Don't trust an activity to be doing anything when the user isn't looking at it.
I have an activity which starts a service through a button press. During service initialization, if an error occurs, this error is displayed by a notification, as follows:
String tickerText = getString(R.string.init_error);
Notification notification = new Notification(
R.drawable.ic_stat_notify_msg,
tickerText, System.currentTimeMillis());
PendingIntent notificationIntent = PendingIntent.getActivity(
this, 0, new Intent(this, MyServiceActivity.class), 0);
notification.setLatestEventInfo(this,
getText(R.string.init_error_tts_title),
getText(R.string.init_error_tts_text),
notificationIntent);
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nm.notify(R.string.init_error, notification);
stopSelf();
When the notification appears in the status bar, I open the notifications window. Then, when I click on the notification, a new instance of MyServiceActivity is launched... Why?
Try to add this attribute on your activity tag on the manifest :
android:launchMode=["multiple" | "singleTop" |
"singleTask" | "singleInstance"]
with value singleTop or singleInstance
Activity Element Documentation
I have a music player that has the initial launcher activity, then a selection activity and then the player. The notification needs to return the user to the player. I used Christophe's idea and found that putting
android:alwaysRetainTaskState="true"
android:launchMode="singleTop"
in the manfest's activity tag of the PLAYER ACTIVITY gave me the correct behavior. Then make sure your notification invokes the PLAYER ACTIVITY class. I didn't do this at first. It invoked the app launcher class and, while this was okay for newer Androids, it left me with the extra activity problem in Android 2.3.6. Now all is good.
If my activity fix doesn't work for you, you'll have to brute-force your way through the choices found at
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
I should add that my player is stateless, just four buttons connected to a service. But if your activity needs its state set up when the notification's intent comes in, you need to override onNewIntent:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
Kudos to Christophe. This is a hard question to get the right answer for.
set a proper launch mode, or add the required intent flags.
I currently have a notification that displays in the notification bar and when the user clicks it it should bring them to the root Activity of my application.
I have used android:finishOnTaskLaunch ="true" & android:clearTaskOnLaunch="true" in my manifest to achieve this when the user presses the app icon from the apps screen or the home screen. The user is always taken to the root activity as expected.
However when I use the following code from my notification the user gets taken to the last screen they were on rather than the root activity which is StartActivity.
Does anyone know what I'm doing wrong?
Intent notificationIntent = new Intent(this, StartActivity.class);
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(), getString(R.string.notification_app_name), notificationText, contentIntent);
mNotificationManager.notify(1, notification);
Adding these flags helps however it still doesn't work after a restart:
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
When I restart my application I set a service running which pops up the notification and when I do this the notification reverts back to the old undesired behavior .
SOLVED:
Solved the issue by adding this flag to the contentIntent of my notification - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED.
Here is an link with some excellent information on the area Google dev group
try this 2 properties
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
is there a way to awake already running app from the notification bar after c2dm message?
i have this app that is registered with c2dm servers that receives push notifications from my server to do some processing. so after i receive c2dm message from my server, it displays the status bar notification to the user, user expands the notifications and clicks on my app, brings it up.
all is good but if this app was already running before (stared from the icon) this would load another instance of my app into memory. also some of the things are crashing in it. i already changed the android:launchMode="singleTop" on all my activities, i tried using intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) in my notification and no luck. i always end up with 2 apps running.
any help is appreciated
here my static function that i use to create a notification after i receive the c2dm message:
public static void notifyStart(Context context, String notificationText) {
//notification
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
int icon = R.drawable.icon_notify;
CharSequence tickerText = notificationText;
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 400;
notification.ledOffMS = 400;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
CharSequence contentTitle = "App Name";
CharSequence contentText = notificationText;
Intent notificationIntent = new Intent(context, home.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(1350, notification);
}
and here is my home activity:
<activity android:name=".home"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
guys, i am very sorry but it was my fault :| couple of days ago i decided to change the name of the package of my app and forgot to remove the old app from the phone. i didn't realize that it would cause two separate installations on my phone, the task manager displays only app name so it did look like there were two instances of the same app, in fact there was one instance of each ;) sorry about trouble and appreciate your willingness to help :)
Android documentation says:
As shown in the table below, the modes fall into two main groups, with "standard" and "singleTop" activities on one side, and "singleTask" and "singleInstance" activities on the other. An activity with the "standard" or "singleTop" launch mode can be instantiated multiple times. The instances can belong to any task and can be located anywhere in the activity stack. Typically, they're launched into the task that called startActivity() (unless the Intent object contains a FLAG_ACTIVITY_NEW_TASK instruction, in which case a different task is chosen — see the taskAffinity attribute).
In contrast, "singleTask" and "singleInstance" activities can only begin a task. They are always at the root of the activity stack. Moreover, the device can hold only one instance of the activity at a time — only one such task.
so it seems (though I haven't checked) that singleInstance is what you're looking for.
see: http://bit.ly/gH8SBb