背景
我有一个有多个活动的任务(即app)。
问题
如何将任务带到前面,而无需为该任务重新排序活动堆栈?
USER SCENARIO
当设备启动时(即收到android.intent.action.BOOT_COMPLETED广播后),我的应用程序启动,调用此任务1,并显示活动A(下面的代码)。当用户与任务1交互时,他/她在堆栈上打开活动B(活动B现在当前显示在屏幕上)。接下来,用户点击主页键并打开其他任务,将其命名为任务2,然后锁定屏幕。用户解锁屏幕,我的应用程序广播并接收android.intent.action.USER_PRESENT意图(请参阅下面的清单摘录)。我按照预期在我的IntentReceiver类中执行startActivity()调用,但不是仅将任务带到前台,而是创建一个新任务,将其称为任务3.
我已经尝试改变
如果我修改或更改Intent.FLAG_ACTIVITY_NEW_TASK到任何其他意图,那么我收到此错误消息:
从Activity上下文外部调用startActivity()需要 FLAG_ACTIVITY_NEW_TASK标志。这真的是你想要的吗?
...所以看起来我必须使用Intent.FLAG_ACTIVITY_NEW_TASK。
如果我将主活动的lauchMode更改为“singleTask”,则将正确的任务置于前台(即不创建新任务),但重新排序活动堆栈,使activity_A位于堆栈顶部。
此时我不知道如何在侦听android.intent.action.USER_PRESENT意图的同时将现有任务带到前台而没有重新排序活动堆栈,任何帮助都将不胜感激。
BTW,这个应用程序正在公司拥有的Android设备上交付给一组员工,而不是一般公众。
CODE SNIPPETS
要启动应用程序,我在清单文件中设置了广播接收器。
<application
:
<activity
android:label="@string/app_name"
android:launchMode="singleTop"
android:name=".activities.activity_A" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
:
<receiver
android:enabled="true"
android:name=".utilities.IntentReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
在我的IntentReceiver课程中,我开始了我的主要活动......
public class IntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, activity_A.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
答案 0 :(得分:5)
这是一个对我有用的略显黑暗的实现:
创建一个简单的BringToFront活动,finish()
上只有onCreate()
本身:
public class BringToFront extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
finish();
}
}
在您的BroadcastReceiver中,如果操作为USER_PRESENT,则启动上面的BringToFront活动而不是您的activity_A:
@Override
public void onReceive(Context context, Intent intent) {
Class<? extends Activity> activityClass = activity_A.class;
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
activityClass = BringToFront.class;
}
Intent i = new Intent(context, activityClass);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
这是有效的,因为BringToFront活动与您的activity_A具有相同的taskAffinity
,并且启动它将使系统将现有任务带到前台。然后BringToFront活动立即退出,将您任务的最后一个活动(场景中的activity_B)带到前面。
值得注意的是,在API级别11(Honeycomb)上,moveTaskToFront()
方法被添加到系统的ActivityManager服务中,这可能是更好的实现方式你想要什么。
答案 1 :(得分:0)
好的,我可以通过在主要活动(activity_A)中添加静态全局变量来实现此功能。在onCreate中,我设置了isRunning = true,并且onDestory = false。然后在我的IntentReceiver类中,我检查isRunning以确定要启动哪个活动:
:
if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
if (GlobalVariables.isRunning) {
activityClass = BringToFront.class;
} else {
activityClass = activity_A.class;
}
} else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
activityClass = activity_A.class;
}
: