I am creating application that shows notification icon in statusbar. When user opens statusbar and taps on the icon the application should be launched.
I am searching a way to avoid re-creation of application during this launch. I have created test application and add log messages to handlers onCreate, onRestart, onResume, onStop and onDestroy. Log messages demonstrates the problem:
- User starts application - onCreate, onResume
- User presses HOME button - onStop
- User opens list of applications and starts application again - onRestart, onResume
- User presses HOME button - onStop
- User opens list of recent applications and selects the application - onRestart, onResume
- User presses HOME button - onStop
- User opens statusbar and taps on the application icon - onDestroy, onCreate, onResume.
Step 7 has a different behavior then 3) and 5) - there is onDestroy here. In other words, instance of the application is recreated. Is it possible to avoid this recreation?
This is a code of my test activity:
public class MainActivity extends Activity {
private final String LOG_TAG = "com.example.notificationtest";
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showNotification(this);
Log.d(LOG_TAG, "NotificationTest: OnCreate");
}
@Override protected void onRestart() {
super.onRestart();
Log.d(LOG_TAG, "NotificationTest: OnRestart");
}
@Override protected void onResume() {
super.onResume();
Log.d(LOG_TAG, "NotificationTest: OnResume");
}
@Override protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "NotificationTest: OnDestroy");
}
@Override protected void onStop() {
super.onStop();
Log.d(LOG_TAG, "NotificationTest: OnStop");
}
private static final int NOTIF_ID = 91371;
public static void showNotification(Context context) {
final Intent result_intent = new Intent(context, MainActivity.class);
result_intent.setAction(Intent.ACTION_MAIN);
result_intent.addCategory(Intent.CATEGORY_LAUNCHER);
//result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
//result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder stack_builder = TaskStackBuilder.create(context);
stack_builder.addParentStack(MainActivity.class);
stack_builder.addNextIntent(result_intent);
PendingIntent pending_intent = stack_builder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(context);
Resources res = context.getResources();
builder.setContentIntent(pending_intent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker("test")
.setWhen(System.currentTimeMillis())
.setAutoCancel(false)
.setContentTitle("title")
.setContentInfo("cinfo")
.setContentText("ctext");
Notification n = builder.build();
n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NOTIF_ID, n);
}
}
There are some flags, that can be set to result_intent, like FLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_CLEAR_TASK and FLAG_ACTIVITY_NEW_TASK. They allow to specify that activity should be restarted on launch (with activity launch mode "singleTop", "singleTask" etc). But what flag should be set to avoid restarting? Probably I should configure pending_intent in some way?
Any help will be very appreciated.
Solved
Thanks a lot for the answers, the problem is solved.
Same problem is described here. I have checked test project from that topic and found difference with my code. To solve the problem my code should be changed in follow way:
final Intent result_intent = new Intent(context, MainActivity.class);
//result_intent.setAction(Intent.ACTION_MAIN); // (1)
//result_intent.addCategory(Intent.CATEGORY_LAUNCHER); // (2)
result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
another set of flags works too:
result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
main point was to comment lines (1) and (2)