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

4

47

I'm experiencing the problem described in this Android issue: http://code.google.com/p/android/issues/detail?id=4536

Simply put, after pressing the HOME button, android prevents services and broadcast-receivers from calling startActivity for 5 seconds.

I've also noticed that (well, theoretically), having the following permission :

"android.permission.STOP_APP_SWITCHES"

allows you to call resumeAppSwitches (which is defined in ActivityManagerService). Looking at the latest version of ActivityManagerService, this code is removed.

The question: How to launch an activity using startActivity without this 5 second delay?

Cyrilla answered 8/4, 2011 at 19:47 Comment(1)
You should contact the guys at WidgetLocker (they used at least to read this thread: forum.xda-developers.com/showthread.php?t=825553 ). They have a way to bypass those 5 seconds but I think it requires root. Maybe they'll tell you something useful?Mahatma
K
18

I don't think there is a way to do it with the current APIs. I think that is how they intended it to work so that an app cannot force itself back open when the user exits with a home key press. You could add the home/ launcher intent to the filter for whatever activity it is you are trying to start. Then the user would have the choice to basically treat that app as though it is a homescreen. Then it would get launched with no delay at all whenever the user presses the home button(They'd have to select it from the list that will pop up asking which app they want to use to complete this action, but they could check always use this app to take this step away in the future.)

Kenishakenison answered 8/4, 2011 at 19:57 Comment(6)
Thanks. My app is 'Wave Launcher' which is (as the name suggests) a launcher by itself. It is controlled by a background service and not an activity, hence the problem. (it doesn't replace the default home app, it's an add-on). Since I've already thoroughly investigated this issue, I'm looking for much less trivial answer.Cyrilla
I was working on a different type of project but was interested in trying to get this effect (trigger a startActivity() call to happen when the home button was pressed.) not too long ago. I never came up with a way to get rid of the few second delay. If you figure it out do post it here for us =).Kenishakenison
I've decided to accept your answer. Although there's no actual solution, and although I haven't learned something new from it. It's probably the correct answer. This was my assumption to begin with, and posting the question here was a long-shot. Thanks.Cyrilla
I guess you've looked at the simple Activity.onUserLeaveHint() and this has the 5second delayGotha
In my situation, this was an actual solution. The goal was to create "Kiosk" mode, and since we had access to the device before shipping to customers, we were able to run through pressing home and selecting "Always use our app" from the selection pop-up.Froghopper
Is there any solution for this issue? Any workaround?Selig
G
56

Here is a solution I found.

Put your intent that you want to start immediately in a PendingIntent, then call the send() Method on it.

So instead of this

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

just do this

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();
                }
Garold answered 20/3, 2017 at 18:56 Comment(6)
You're my hero. Thanks!Globeflower
This is a very good solution. Calling startActivity from onPause, this immediately starts the new activity though there is a quick flicker.Kofu
@Chinbin check this out please #47124688Chronister
For me, this works up to Android P, but no longer in Android QSudarium
I've been using this in production for a while and seems to have died in Android Q :'(Harl
According to my test, It works <=8.0.0,not work >=8.1.0Northman
K
18

I don't think there is a way to do it with the current APIs. I think that is how they intended it to work so that an app cannot force itself back open when the user exits with a home key press. You could add the home/ launcher intent to the filter for whatever activity it is you are trying to start. Then the user would have the choice to basically treat that app as though it is a homescreen. Then it would get launched with no delay at all whenever the user presses the home button(They'd have to select it from the list that will pop up asking which app they want to use to complete this action, but they could check always use this app to take this step away in the future.)

Kenishakenison answered 8/4, 2011 at 19:57 Comment(6)
Thanks. My app is 'Wave Launcher' which is (as the name suggests) a launcher by itself. It is controlled by a background service and not an activity, hence the problem. (it doesn't replace the default home app, it's an add-on). Since I've already thoroughly investigated this issue, I'm looking for much less trivial answer.Cyrilla
I was working on a different type of project but was interested in trying to get this effect (trigger a startActivity() call to happen when the home button was pressed.) not too long ago. I never came up with a way to get rid of the few second delay. If you figure it out do post it here for us =).Kenishakenison
I've decided to accept your answer. Although there's no actual solution, and although I haven't learned something new from it. It's probably the correct answer. This was my assumption to begin with, and posting the question here was a long-shot. Thanks.Cyrilla
I guess you've looked at the simple Activity.onUserLeaveHint() and this has the 5second delayGotha
In my situation, this was an actual solution. The goal was to create "Kiosk" mode, and since we had access to the device before shipping to customers, we were able to run through pressing home and selecting "Always use our app" from the selection pop-up.Froghopper
Is there any solution for this issue? Any workaround?Selig
M
1

I am using AlarmManager to start Activity immediatly from Service. Activity starts without delay, even if you have pressed home button before.

Tested on Android 5.0.1 (Galaxy Alpha).

Don't work at 6.0.1 (Nexus 7 2013) :-(

Don't work at 4.1.2 (Galaxy S II) :-(

Don't work at 4.3 (ASUS MeMO Pad FHD 10 ME302C) :-(

@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);
}
Multilateral answered 7/5, 2016 at 12:41 Comment(0)
M
0

I am intrigued by this "feature" also and how to avoid it. Reading the post: http://code.google.com/p/android/issues/detail?id=4536 (read the comment #10).

I quote the relevant part below:

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.

Among those, I believe the best way to do it is to create a "Home Helper"-like activity. So, instead of starting a new activity, you would call this one instead. This is specially true, since you are creating a launcher app.

As I said in my previous comment to the question, I would contact the WidgetLocker developer about it. Alternatively, you can use APK Manager to see how he implemented it (he even encouraged the use of the APK Manager to create different mods to his app, the link to the xda-developers thread is in the comment above)

Mahatma answered 18/4, 2011 at 16:5 Comment(5)
BTW, there is another example of this here: appsbeyond.com/apps/screen-suiteMahatma
Thanks for your answer. My app is a launcher add-on, not a launcher replacement. I'm very familiar with how to write a pre-home home (Already have an app in the market that can act like one). Generally speaking, I think this is a bad approach, mostly due to launcher reloads that you've mentioned. The best thing I'm taking from your answer is to launch apps as root. I'll have to check how this is done.Cyrilla
I'm afraid there are not too many options available. The problem with the root is that it will greatly limit how many people will be able to run it.Mahatma
I have proved out that root can get around this 5 second delay. The app will need to be moved to the /system/app directory and you need to add the permission to your manifest: "android.permission.STOP_APP_SWITCHES".Madagascar
Can someone provide a little example for point 2) from Aleadam? Thx in advance!Boilermaker

© 2022 - 2024 — McMap. All rights reserved.