最近做的一个小软件中遇到一个情况,就是想通过Service来产生Notification,再通过点击Notification来打开应用。
但是随之而来一个问题是,我所希望的是如果应用程序是处于打开状态,则不用重新打开应用程序然后再做一些操作;如果应用程序没有处于打开状态,则打开应用程序然后做一些不同于前者的操作。
后来想到了用Itent.setFlags来操作,如果不想在应用程序打开的状态下重新打开应用程序,则应该设置为:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.
The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP
in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP
is set then this Intent will be delivered to the current instance's onNewIntent().
This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK
: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.
对于FLAG_ACTIVITY_SINGLE_TOP:
If set, the activity will not be launched if it is already running at the top of the history stack.
但是,我想要的是要让程序自己知道自己是通过点击Notification来打开的,于是想到了Intent.putExtra,只是对的。
不过,我还想要在程序从打开状态或未打开状态下进入打开状态时做不同的事,所以就想到了在打开的Activity中去获取Intent,即在onResume中去获取。
思路很对,可是之后发现当应用程序是在打开状态下点击的Notification,在onResume中捕捉不到我从Service发过来的Intent,而且即使接受到了,那应用程序也不知道自己之前是打开的还是未打开的(因为从后台发过来的inten的参数t都是一样的)。
之后我仔细看了上面两段英文,是android中java doc对于这两个Intent.setFlags参数的讲解,请注意:The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP
in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP
is set then this Intent will be delivered to the current instance's onNewIntent().
所以,如果是应用处于打开状态,那么我们是不能在onResume中去捕捉到我们Service传过来的Intent的,因为我们设置了FLAG_ACTIVITY_SINGLE_TOP,并没有重新产生一个activity。而此时,我们可以在activity中的onNewIntent()中来捕获到。
因此,我们就能区分出在进入应用之前应用是处于打开状态或是关闭状态。
主要源码:
(1)在Activity中
@Override
protected void onResume() {
//TODO DELETE
Intent intent=this.getIntent();
if(intent.getBooleanExtra("fromService", false)==true)
{
Log.v("点击状态栏,而且应用之前处于未运行状态", "!!!!");
intent.removeExtra("toGuaiWindowAndRefresh");
}
Log.v("onresume", "!!!!");
super.onResume();
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
if(intent.getBooleanExtra("fromService", false)==true)
{
Log.v("点击状态栏,而且应用处于打开状态","!!!!");
}
}
(2)在Service中:
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(); //定义消息
notification.icon = getResources().getIdentifier("ic_launcher", "drawable", getApplicationInfo().packageName); //获取应用程序下的图标资源文件作为任务栏图标
notification.tickerText = "发来了新消息!"; //显示的消息
notification.flags|=Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, AppForDaisyActivity.class); //设置任务栏拉下点击的链接
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("fromService", true);//设置参数
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,intent, 0);
notification.setLatestEventInfo(this, "发来了新消息!", "点击查看", contentIntent);
notificationManager.notify(0, notification);