Android - 从广播接收器启动应用程序

Android - launch app from broadcast receiver

我希望广播接收器以这种方式启动我的应用程序:

  1. 如果应用程序不在前台或后台,启动它就像从启动器启动一样。

  2. 如果应用程序在后台,将其以上次的状态带到前台。

  3. 如果应用程序在前台,什么也不做。

这是我的代码:

@Override
public void onReceive(Context context, Intent intent) {
        Intent launch_intent = new Intent("android.intent.action.MAIN");
        launch_intent.setComponent(new ComponentName("com.example.helloworld","com.example.helloworld.MainActivity"));
        launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        launch_intent.addCategory(Intent.CATEGORY_LAUNCHER);
        launch_intent.putExtra("some_data", "value");
        context.startActivity(launch_intent);
}

MainActivity 是我的根 activity。就像我说的,如果应用程序已经 运行,我只想将它带到前面而不改变其状态。如果MainActivity上面有一些activity,就保持原样。

大部分时间上面的代码工作正常,但有时我注意到应用程序在从后台启动时被重新启动(或者状态被重置---根回到顶部)。

我应该使用什么代码?感谢您的帮助!

假设您已经了解 BroadcastReceiver,您只需像通常在 onReceive 上那样执行启动 :因此它看起来像这样

@Override
public void onReceive(Context context, Intent intent) {
    Intent launch_intent = new Intent("android.intent.action.MAIN");
    launch_intent.putExtra("some_data", "value");
    tiapp.startActivity(launch_intent);
}

如果之前启动过,它会恢复那个Activity,如果没有,它会启动一个新的

@Override
public void onReceive(Context context, Intent intent) {
    Intent launch_intent = new  Intent(context, MainActivity.class);
    launch_intent.setComponent(new ComponentName("com.example.helloworld","com.example.helloworld.MainActivity");
    launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP |INTENT.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
    launch_intent.putExtra("some_data", "value");
    launch_intent.addCategory(Intent.CATEGORY_LAUNCHER);
    context.startActivity(launch_intent);
}

就这么简单,但是除非您知道在尝试从意图中获取额外数据时的正确方法,否则您通常会遇到 java 空指针异常。

使用onNewIntent()方法接收额外数据。如果你想知道如何在下面评论。

编辑: 尝试以下操作。但我不明白的是我给你的第一个代码应该自己工作。它一直对我有用。你确定你已经复制了我给你的第一个代码并在没有做任何修改的情况下粘贴了吗?

编辑2: 如果这不起作用,请尝试将标志设置为 clearTaskOnLaunch 而不是 INTENT.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

您不需要编写所有代码。可以使用一个"launch Intent",如下:

PackageManager pm = context.getPackageManager();
Intent launchIntent = pm.getLaunchIntentForPackage("com.example.helloworld");
launchIntent.putExtra("some_data", "value");
context.startActivity(launchIntent);

但是,您的代码应该也可以工作。

如果您说这在大多数情况下都有效,那么在这些情况下您可能会看到一个令人讨厌的旧 Android 错误。当您直接从安装程序或通过 IDE(Eclipse、Android Studio 等)首次 启动您的应用程序时,会发生这种情况。您应该始终直接从主屏幕或已安装应用程序列表首次启动您的应用程序。有关此令人沮丧的 Android 错误的更多信息,请参阅

因为你需要像

这样的行为

1) 如果应用程序不在前台或后台,则启动它就像从启动器启动一样。

2) 如果应用程序在后台,则将其带到前台并保持上次的状态。

3) 如果应用程序在前台,什么也不做。

考虑:

@Override
public void onReceive(Context context, Intent intent) {

    Intent startIntent = context
            .getPackageManager()
            .getLaunchIntentForPackage(context.getPackageName());

    startIntent.setFlags(
                    Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |
                    Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
    );
    context.startActivity(startIntent);
}