关于android:按下HOME按钮后,无需5秒的延迟即可从服务启动活动

Starting an activity from a service after HOME button pressed without the 5 seconds delay

我遇到此Android问题中描述的问题:
http://code.google.com/p/android/issues/detail?id=4536

简而言之,在按下HOME按钮后,Android会阻止服务和广播接收者调用startActivity 5秒钟。

我还注意到,(理论上),具有以下许可:

1
"android.permission.STOP_APP_SWITCHES"

允许您调用resumeAppSwitches(在ActivityManagerService中定义)。
查看最新版本的ActivityManagerService,将删除此代码。

问题:如何在不延迟5秒钟的情况下使用startActivity启动活动?


这是我找到的解决方案。

将要立即开始的意图放入PendingIntent中,然后在其上调用send()方法。

所以代替这个

1
2
3
Intent intent = new Intent(context, A.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);

只是这样做

1
2
3
4
5
6
7
8
9
Intent intent = new Intent(context, A.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                PendingIntent pendingIntent =
                        PendingIntent.getActivity(context, 0, intent, 0);
                try {
                    pendingIntent.send();
                } catch (PendingIntent.CanceledException e) {
                    e.printStackTrace();
                }


我认为目前的API没有办法做到这一点。我认为这就是他们希望其工作的方式,以便当用户按下主键退出时,应用程序无法强制自己重新打开。您可以将home /启动器意图添加到过滤器中,以进行尝试启动的任何活动。然后,用户可以选择将该应用程序基本视为主屏幕。然后只要用户按下主屏幕按钮,它就会立即启动(他们必须从弹出的列表中选择它,询问他们要使用哪个应用来完成此操作,但是他们可以检查是否始终使用这个应用程式,可让您日后迈出这一步。)


我正在使用AlarmManager从Service立即启动Activity。
即使没有按下主页按钮,活动也会立即开始。

在Android 5.0.1(Galaxy Alpha)上进行了测试。

不要在6.0.1(Nexus 7 2013)上工作:-(

不要在4.1.2(Galaxy S II)上工作:-(

不要在4.3(ASUS MeMO Pad FHD 10 ME302C)下工作:-(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@TargetApi(Build.VERSION_CODES.KITKAT)
private void startActivity() {

    Intent intent = new Intent(this, Main.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    long now = Calendar.getInstance().getTimeInMillis();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, now, pendingIntent);
    else
        alarmManager.set(AlarmManager.RTC_WAKEUP, now, pendingIntent);
}

我对这个"功能"以及如何避免它也很感兴趣。阅读帖子:http://code.google.com/p/android/issues/detail?id=4536(阅读评论#10)。

我引用以下相关部分:

Workarounds are:

1) Don't use an
activity, do everything from a
service.

2) Have some kind of
intermediate Home (WidgetLocker
HomeHelper, QuickDesk, PowerStrip,
etc). These do a startActivity
immediate to start the"real" Home and
this bypasses the 5 second rule. This
is a bad idea as Android prioritizes
keeping the system Home in memory but
not whatever secondary Home the
intermediate set. So it can lead to
Launcher reloads which is no fun. Plus
it's very confusing to users.

3) Root
can start activities during this
period.

我认为,其中最好的方法是创建类似"家庭助手"的活动。因此,与其开始一项新活动,不如称其为"新活动"。这是特别正确的,因为您正在创建启动器应用程序。

正如我在对该问题的先前评论中所说,我将与WidgetLocker开发人员联系。或者,您可以使用APK Manager查看其实现方式(他甚至鼓励使用APK Manager为他的应用创建不同的Mod,上面的评论中指向xda-developers线程的链接)