Android 从通知恢复应用程序和堆栈

Android 从通知恢复应用程序和堆栈,android,Android,我想从状态栏通知中恢复我的应用程序,方式与用户点击启动器中的图标时完全相同 也就是说:我希望堆栈处于与用户离开前相同的状态 在通知上设置挂起意图时的问题是,它始终以特定活动为目标。我不要这个。我需要像启动器一样恢复应用程序 因此,如果用户在活动A中,我希望恢复活动A。如果他从活动A启动了活动B,那么我希望在用户点击通知时显示B,并恢复堆栈,以便在用户点击B中的后退按钮时恢复A 还有两个类似标题的问题,但没有一个能解决我的问题。可能有一个更简单的方法,但你可以将数据存储在sqlite数据库中,每当

我想从状态栏通知中恢复我的应用程序,方式与用户点击启动器中的图标时完全相同

也就是说:我希望堆栈处于与用户离开前相同的状态

在通知上设置挂起意图时的问题是,它始终以特定活动为目标。我不要这个。我需要像启动器一样恢复应用程序

因此,如果用户在活动A中,我希望恢复活动A。如果他从活动A启动了活动B,那么我希望在用户点击通知时显示B,并恢复堆栈,以便在用户点击B中的后退按钮时恢复A


还有两个类似标题的问题,但没有一个能解决我的问题。

可能有一个更简单的方法,但你可以将数据存储在sqlite数据库中,每当你重新启动应用程序时,无论你在数据库中保存了什么状态,你都可以检索并设置你的值

只需使用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);
由于您从通知栏创建的用于打开您的
活动的
意图
与用于启动应用程序的Android相同,因此将显示以前打开的
活动
,而不是创建新活动。

这非常简单
打开清单文件,在创建活动的活动属性中设置属性启动模式,然后设置类别和相应的标志。。。 这就是我的工作方式,我必须这样做,因为我这样做是为了支持Api lvl 8

在安卓舱舱单上

android:launchMode="singleTask"

因此,这个把戏的关键在于意图。标志活动将你带到最前面,以及清单中设置的行


希望对其他人有所帮助。

我也遇到了同样的问题,并尝试解决这个问题,如@GrAnd的答案:

final Intent notificationIntent = new Intent(context,YourActivity.class);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
这是可行的,毫无疑问,但问题是当你把你的意图设定为主要行动时。那么您将无法将任何捆绑设置为意图。我的意思是,您的原始数据将不会从目标活动接收,因为ACTION_MAIN不能包含任何额外的数据

与此相反,您可以将活动设置为singleTask并正常调用您的意图,而无需设置ACTION_MAIN并从目标活动的onNewIntent()方法接收意图

但是如果你打电话给beaware,super.onNewIntent(intent);然后将创建该活动的第二个实例


<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);
          }
        }
      }
    }
}
private void BringApplication前台(){ ActivityManager am=(ActivityManager)getSystemService(Context.ACTIVITY_服务); if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){ List tasksList=am.getAppTasks(); 对于(ActivityManager.AppTask任务:TaskList){ task.moveToFront(); } }否则{ List tasksList=am.getRunningTasks(Integer.MAX_值); 如果(!tasksList.isEmpty()){ int nSize=tasksList.size(); 对于(int i=0;i
对于您不想/无法硬编码启动器活动的情况,此解决方案有效

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 launcher的意图进行了比较,发现pkg没有设置在那里,所以我就这样从意图中删除了包名

我的特殊情况是,通知是在库中创建的,因此我无法知道启动器活动是什么。

最终解决方案:


只是一个问题:如果一个特定的/替代的启动器使用了一个稍微不同的意图会怎样?也许还有其他一些额外的东西或类别。。你认为我应该缓存启动我的应用程序的原始意图(由Activity.getIntent()检索),并按原样创建挂起的意图吗?我为自己工作,我有两个activate splash和mainactivity,在使用上述代码修改代码后,它将恢复mainactive,而不启动新的活动。非常感谢……这对我没用,请帮帮忙。我试着用Nexus5。试着用棒棒糖,它不起作用。只是打开一个新的“YourActivity”有什么方法可以做到这一点,并传递新的附加内容吗?可能重复:,这是否回答了您的问题?你在什么API上测试这个?它在API 23上似乎不起作用。按“上一步”,然后单击通知将启动该活动的第二个实例否否。只是否;)工作完美。但在我的情况下,我需要传递一些数据,当应用程序完全退出并能够在onCreate-Intent中获取数据时,它工作正常,而当应用程序在后台运行时,我无法从Intent中获取数据。您能告诉我,这看起来是唯一的工作解决方案,但如果需要,为您设置标志\活动\重置\任务\吗?谢谢,托马斯。经过数小时的挣扎,你救了我。@Prat for app running,你将在onNewIntent()中获得数据-更多信息最终一个答案如预期的那样有效,它非常有效!无论如何,指定活动是没有意义的,因此即使其他解决方案有效,这个解决方案也更清晰
Intent.FLAG\u ACTIVITY\u TO \u FRONT
不起任何作用,
android:launchMode=“singleTask”
不建议使用,即使在定向和其他配置更改期间,也不会重新创建活动您是否可以使用API lvl 8进行尝试?已经六年了,我想已经有很多变化了。顺便说一句,把它标记为无用是很粗鲁的。
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();
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
        }
    }