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