Android - 点击通知显示当前活动,如果应用程序已关闭则启动新活动

3
我有一个带服务和持续通知的应用程序和两个活动:Activity AActivity B。在Activity A中有一个按钮,可以启动Activity B。当单击通知时,我希望出现以下情况:
  1. 如果应用程序关闭 -> 用Activity A启动应用程序。
  2. 如果应用程序在前台或后台(打开的应用程序列表)中已打开,不论是在哪个活动中 -> 显示当前活动而无需启动新的Activity A。也就是说,如果我在Activity B中 -> 显示当前的Activity BActivity A也是一样而无需启动新的。
我搜索了很多,最终找到了这个答案,其中提到需要执行以下操作:
final Intent notificationIntent = new Intent(context, ActivityA.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

在清单文件中,我有如下内容:
请注意,我使用了 android:launchMode="singleTop"
(说明:该段话是关于Android应用程序开发中Manifest文件配置的相关内容)
    <activity
        android:name=".ActivityA"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:theme="@style/AppTheme.NoActionBar"></activity>
    <activity
        android:name=".ActivityB"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:theme="@style/AppTheme.NoActionBar"></activity>

似乎它的表现不够稳定,如果按照以下步骤操作,则从不起作用:启动应用程序 -> 启动 Activity A -> 启动服务(显示通知) -> 转到 Activity B -> 单击通知打开 Activity A

我想知道是否有更好的一致性解决方案:


哪个 Activity 是具有 CATEGORY=LAUNCHER 和 ACTION=MAIN 的那一个? - undefined
1个回答

2

当然它总是会打开ActivityA, 因为你在这里定义了它:

final Intent notificationIntent = new Intent(context, ActivityA.class);

你需要做的是定义你在结束时所处的位置。下面是我处理这个问题的方法:

创建一个类并将其扩展自Application类。

在此处定义一个变量,它可以是布尔型、枚举型、整型等等......当你进入这些活动中的任何一个时,改变该参数。

在每个活动的OnDestroy函数中将特定的变量重置为其默认值。

在你的服务中,在启动Intent之前,检查你上次所处的状态,并根据那个状态制作你的Intent。

public class MY_APPLCIATION extends Application {
    public static Boolean ActivityAIsRunning=false;
    public static Boolean ActivityBIsRunning=false;
}

覆盖两个活动的onResume和onDestroy:

public class ActivityA extends AppCompatActivity {
    // ......
     @Override
protected void onDestroy() {
    super.onDestroy();
    MY_APPLCIATION.ActivityAIsRunning=false;
}

@Override
protected void onResume() {
    super.onResume();
    MY_APPLCIATION.ActivityAIsRunning=true;
}
}

ActivityB :

public class ActivityB extends AppCompatActivity {
    // ......
     @Override
protected void onDestroy() {
    super.onDestroy();
    MY_APPLCIATION.ActivityBIsRunning=false;
}

@Override
protected void onResume() {
    super.onResume();
    MY_APPLCIATION.ActivityBIsRunning=true;
}
}

现在有一个要注意的技巧:
当你创建通知时,你应该定义意图!你需要有另一个活动(我们称它为MY_NOTIFICATION_ACTIVITY),通知应该始终发送到这个活动。现在在那个活动中检查设置的布尔值,然后调用所需的活动(ActivityA或ActivityB)。不要忘记,在清单文件中,你也应该将ActivityB设置为singleInstance!
*** 另一种简单的方法
另一种简单的方法是在每个活动的OnResume中更新通知。进入每个活动时,你可以将意图更改为所需的活动,并创建相同的通知并更新最后一个通知。

我按照你的建议使用了重定向活动,并在那里检查了布尔值,然后使用适当的活动执行了startActivity()。显然,startActivity将始终启动一个新的活动实例。当你写道“调用所需的活动(ActivityA或ActivityB)”时,你是如何“调用”它的? - undefined
在您的清单文件中设置您的活动启动模式为android:launchMode="singleInstance"。@OfekAgmon - undefined
我把它们两个都改成了"singleInstance",但效果并不太好,活动之间的过渡看起来并不流畅,实际上有点像是结束了当前活动然后启动了一个新活动。我认为最好的选择可能是每次布尔值发生变化时更新通知的意图,尽管这需要做很多工作。 - undefined
防止单例实例化活动!不要结束任何东西。检查您传递给意图的标志 @OfekAgmon - undefined
什么是更简单的方法?@DavidWasser - undefined
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接