我正在开发一个具有许多活动的应用程序。我想创建一个持续的通知,该通知(或多或少)说:“ AppName-返回AppName”,每当我的背景服务运行时都会存在。 创建和处置通知是没有问题的。

现在,用户可以在几个屏幕/活动中的任何一个中,离开应用程序,然后希望通过通知重新输入应用程序。 问题是, ,该通知必须有一个意图,它启动了 预定的活动. 。我希望通知将应用重新输入 任何活动都位于历史堆栈的顶部.

我第一次尝试进行丑陋的解决方法是进行一项活动(让我们称之为“ returnfromnotify”),其唯一的工作是在“ on Create”中“完成”自己。该通知将在应用程序历史记录范围内打开“ returnfromnotify”,然后立即删除自身,将用户发送回应用程序堆栈中的先前历史记录状态。这似乎有效...除非用户使用“返回”完全退出应用程序。然后,当他们击中通知时,“ returnfromnotify”负载,然后完成,将其发送回主屏幕(因为该应用程序的历史记录堆栈中没有活动)。

我考虑过试图检测“ returnfromnotify”之前的历史堆栈中是否有任何东西,如果没有,请激发我的主要活动。我似乎也找不到这样做的方法。

Java/Android新手有任何意见或建议吗?仅供参考,我的主要历史是基于脚本的语言。

有帮助吗?

解决方案

我喜欢您最初创建“ returnfromnotify”活动的想法,比您提出的解决方法更好 可以检测重新反应是否在堆栈的底部(因此,堆栈中的唯一活动)。

您可以做到这一点:

将您的恢复性添加到清单中,并指定 没有历史 属性:

<activity android:name=".ResumeActivity" android:noHistory="true" />

指定没有史将确保此活动在完成后不会立即留在堆栈中。这样,您就会知道,只有当前的重新反应实例才会出现在堆栈中。

为了检查应用程序堆栈,您还必须要求get_tasks许可:

<uses-permission android:name="android.permission.GET_TASKS" />

现在您可以使用 ActivityManager :: getRunningTasks() 确定重新反应是否是堆栈中的唯一活动:

public class ResumeActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(isOnlyActivityInStack()) { //check the application stack
            //This activity is the only activity in the application stack, so we need to launch the main activity
            Intent main = new Intent(this, MainActivity.class);
            main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(main);
        } else {
            //Return the user to the last activity they had open
            this.finish();
        }
    }

    /**
     * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack
     *
     * @return  boolean  This activity is the only activity in the stack?
     **/
    private boolean isOnlyActivityInStack() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        boolean onlyActivityInStack = false;

        for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) {
            if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack
                if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) {
                    //If the ResumeActivity is the base activity, we know that it is the only activity in the stack
                    onlyActivityInStack = true;
                    break;
                }
            }
        }

        return onlyActivityInStack;
    }

}

我知道您2年前问了这个问题,但是我提供了这个答案,以防其他人遇到这种特殊情况(就像我一样)。我认为您最初正在努力的解决方案处于正确的轨道。

其他提示

好吧,我相信我找到了令人满意的工作 对于我的具体情况. 。我在“主动脉”中添加了一个静态整数,每次启动“ ongreate”时,它都会增加整数。每次被解雇时,它都会减少。

在我的“ returnfromnotify”中,我查看静态整数,以查看它是否大于0。如果是这样,我认为有一个主动的“ mainActivity”,并且在“ returnfromnotify”内部运行的“完成”将返回那里。否则,它假设用户已经“备份”,完成自己,然后使用“起始性”来启动“ Main Activity”的新实例。

这不是通用的解决方案,而是出于我的目的,我认为这足够了。我仍然对其他答案开放,如果有人可以在我的逻辑上打孔,请这样做 - 建设性 欢迎批评. 。谢谢。

我想没有简单的方法可以做到这一点 应用:

对于需要维护全球应用状态的人的基础。您可以通过在AndroidManifest.xml的标签中指定其名称来提供自己的实现,这将在创建应用程序/软件包的过程时为您实例化该类。

我会在那里介绍逻辑,并有一种类似的方法:

public Intent getIntentForLastActivityShown();

单击通知项目时被调用。

我的第一种方法是使用 SharedPreferences 并存储一个称为类似的钥匙值对 lastDisplayedActivity. 。然后在每个活动的 onResume (可能是``on Create'')您会有这样的行:

sharedPreferences.edit().putInteger("lastDisplayedActivity", ReturnFromNotify.THIS_ACTIVITY_NAME);

换句话说,您存储一个全应用变量,指示上次显示哪个活动。然后,您只需从共享流程中获取此变量并启动相应的活动。

我通常使用名为“启动器”的活动来检查我的应用程序的状态 模型 并根据模型规则开始活动(或其他事情)。我放 模型 我的应用程序类中的对象。 模型 可以使用 优先 存储其状态。我这样做是为了避免活动中的静态字段。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top