我想通过状态栏通知恢复我的应用,方式与用户在启动器中点按其图标的方式完全相同。
那就是:我希望堆栈处于与用户离开之前相同的状态。
在通知上设置待处理意图时的问题是它始终以特定活动为目标。我不想要这个。我需要像启动器那样恢复应用程序。
因此,如果用户处于活动A中,我想恢复活动A.如果他已经从活动A启动了活动B,那么我希望在用户点击通知时显示B,并且要恢复堆栈当用户点击B中的后退按钮时,A恢复。
还有其他几个问题与类似的标题,但没有一个解决我的问题。
答案 0 :(得分:143)
使用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);
由于您在通知栏中创建的用于打开Intent
的{{1}}与用于启动应用的Android相同,因此将显示之前打开的Activity
而非创建新的。
答案 1 :(得分:24)
对于您不希望/无法对启动器活动进行硬编码的情况,此解决方案可以正常运行
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启动器的意图进行了比较,并注意到pkg没有设置在那里,所以我想出了如何从意图中删除包名。
我的特殊情况是通知是在库中创建的,所以我无法知道启动器活动是什么。
答案 2 :(得分:4)
创建活动,然后设置类别和相应的标志...... 这就是这对我有用的方式,我必须这样做,因为我这样做是为了支持 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
以及清单中设置的行。
希望对其他人有所帮助。
答案 3 :(得分:3)
我也有同样的问题并尝试解决问题,如@ GrAnd的答案:
final Intent notificationIntent = new Intent(context,YourActivity.class);
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
这是有效的,毫无疑问,但问题是当你将你的意图设置为ACTION_MAIN时。然后,您将无法设置任何捆绑到意图。我的意思是,不会从目标活动接收原始数据,因为ACTION_MAIN不能包含任何额外数据。
除此之外,您可以将您的活动设置为singleTask并正常调用您的意图而不设置ACTION_MAIN并从目标活动的onNewIntent()方法接收意图。
但要注意,如果你打电话,super.onNewIntent(意图);然后将创建活动的第二个实例。
答案 4 :(得分:0)
这很简单 打开您的清单文件,并在您的活动属性中设置属性启动模式 singleTop
答案 5 :(得分:0)
最佳解决方案:Notification to restore a task rather than a specific activity?
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
}
}
答案 6 :(得分:-1)
<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);
}
}
}
}
}
答案 7 :(得分:-4)
可能有一种更简单的方法,但您可以将数据存储在sqlite数据库中,每当您重新启动应用程序时,无论您保存到数据库的状态如何,都可以检索并将值设置为它们所需的值。