【问题标题】:android - notification click shows current activity, if app is closed start new activityandroid - 通知点击显示当前活动,如果应用程序关闭启动新活动
【发布时间】:2016-06-04 15:49:47
【问题描述】:

我有一个带有服务和持续通知以及两个活动的应用:

Activity AActivity B

Activity A 有一个以Activity B 开头的按钮。

点击通知时,我希望发生下一个场景:

  1. 如果应用关闭 -> 使用 Activity A 启动应用。
  2. 如果应用程序在任一活动中在前台或后台(打开的应用程序列表)中打开 -> 显示当前活动而不启动新的Activity A,这意味着如果我在Activity B 中 -> 显示当前的@987654329 @ 和 Activity A 相同,无需启动新的。

找了好久终于找到了这个answer,说需要做:

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".

    <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 的那个?

标签: android android-intent android-activity android-service android-notifications


【解决方案1】:

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

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

你需要做的是定义你最后的位置。 这是我的处理方式:

创建一个类并从应用程序类扩展它

在这里定义一个变量,可以是boolean、enum、int等... 当您输入任何这些活动时,请更改该参数。

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

在您的服务中,在制定意图之前,检查您最后处于哪个状态并根据该状态制定您的意图。

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;
}
}

活动B:

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 成为单一实例!!!

*** 另一个简单的方法

另一个简单的方法是更新每个活动的 OnResume 中的通知。 通过输入每个活动,您可以将意图更改为所需活动并发出相同的通知并更新最后一个通知。

【讨论】:

  • 我按照您的建议使用重定向活动,并在那里检查布尔值,并使用适当的活动执行 startActivity()。显然 startActivity 将始终启动该活动的新实例。当您写“调用所需的活动(ActivityA 或 ActivityB)”时,您是什么意思“调用”它?
  • 在清单中设置活动启动模式 android:launchMode="singleInstance" @OfekAgmon
  • 我把它们都改成了“singleInstance”,而且效果也不是很好,活动之间的过渡看起来不太好,因为它实际上有点完成当前活动并开始一个新活动。我认为最好的选择可能是在每次布尔值更改时更新通知的意图,即使它的工作量很大
  • 单实例阻止创建新的活动实例!没有完成任何事情。检查您传递给意图的标志@OfekAgmon
  • 恕我直言,这仍然是尝试解决此问题的错误方法。它有很多代码,而且效果不佳(正如您从 cmets 流中看到的那样)。有一种简单的方法可以做到这一点,应该可以。我认为还有其他原因导致了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多