也就是说: 我希望堆栈处于用户离开之前的相同状态。
设置挂起意图时的问题是它总是针对特定活动。但我不想要这个。我需要像启动器一样恢复应用程序。
因此,如果用户在A活动中,则我希望恢复A活动。如果他从A活动启动了B活动,则我希望在用户点击通知时显示B活动,并恢复堆栈,以便在B活动中点击返回按钮时恢复A活动。
还有几个其他类似标题的问题,但没有一个解决我的问题。
只需使用与Android在启动应用程序时使用的相同意图过滤器即可:
final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
由于你从通知栏打开Activity
所创建的Intent
与Android用于启动应用程序的相同,因此会显示先前已打开的Activity
而不是创建新的Activity
。
对于不想/无法硬编码启动器活动的情况,此解决方案可行。
Intent i = getPackageManager()
.getLaunchIntentForPackage(getPackageName())
.setPackage(null)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, i, 0);
return new NotificationCompat.Builder(context)
...
.setContentIntent(pendingIntent)
.build();
setPackage(null)部分对我来说非常关键,因为如果没有它,应用程序将无法恢复到先前的任务。我将我的意图与Android启动器的意图进行了比较,并注意到那里没有设置包名称,这就是我想要从意图中删除包名称的原因。
我的特殊情况是通知是在库中创建的,所以我无法知道启动器活动会是什么。
我也遇到了同样的问题,并尝试按照@GrAnd的答案来解决问题:
final Intent notificationIntent = new Intent(context,YourActivity.class);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
这个方案是行得通的,毫无疑问,但问题在于当你将意图设置为ACTION_MAIN时。此时,您将无法向意图设置任何bundle。也就是说,目标活动将无法接收到您的基本数据,因为ACTION_MAIN不能包含任何额外数据。
相反,您可以将活动设置为singleTask,并正常调用意图而不设置ACTION_MAIN,并从目标活动的onNewIntent()方法中接收意图。
但如果您调用super.onNewIntent(intent);,则会创建第二个活动实例,请注意。
创建一个活动,然后设置相应的类别和标志...
这是我的解决方案,我必须这样做是因为我要支持Api lvl 8
intent.addCategory(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClass(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT|
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
在 AndroidManifest 文件中
android:launchMode="singleTask"
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
标志,并在清单文件中设置了相应的行。希望对其他人有所帮助。Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
没有任何作用,不建议使用 android:launchMode="singleTask"
,即使在方向和其他配置更改期间,活动也不会被重新创建。 - user924终极解决方案:通知恢复任务而不是特定活动?
public class YourRootActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (!isTaskRoot()) // checks if this root activity is at root, if not, we presented it from notification and we are resuming the app from previous open state
{
val extras = intent.extras // do stuffs with extras.
finish();
return;
}
// OtherWise start the app as usual
}
}
这很简单,打开您的清单文件并在活动属性中设置属性启动模式singleTop
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
private void bringApplicationToForeground(){
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
List<ActivityManager.AppTask> tasksList = am.getAppTasks();
for (ActivityManager.AppTask task : tasksList){
task.moveToFront();
}
}else{
List<ActivityManager.RunningTaskInfo> tasksList = am.getRunningTasks(Integer.MAX_VALUE);
if(!tasksList.isEmpty()){
int nSize = tasksList.size();
for(int i = 0; i < nSize; i++){
if(tasksList.get(i).topActivity.getPackageName().equals(getPackageName())){
am.moveTaskToFront(tasksList.get(i).id, 0);
}
}
}
}
}
可能有更简单的方法,但您可以将数据存储在SQLite数据库中,每当您重新启动应用程序时,您可以检索保存到数据库中的任何状态,并将其设置为所需的值。