android - Delay while launching activity from service -
i have broadcast receiver receives screen off broadcast, , when screen turned off, launches activity. i've named activity lockscreenactivity. i've added getwindow().addflags(windowmanager.layoutparams.flag_show_when_locked);
in oncreate()
of activity, appears on top of android lockscreen, want. works enough, mostly. problem happens whenever press home button send any app background.
when press home button return home screen app, , press power button turn off screen, , press power button in second turn in on, shows android lock screen. activity gets created 3-4 seconds later. huge delay , unacceptable. in other scenarios, delay not happen. if i've been in home screen time, or other app open, , click power button twice in quick succession, see lockscreenactivity before seeing android lockscreen.
my app has few other normal activities (launched app drawer) , service shows persistent notification. same lockscreenactivity launched whenever notification clicked. interestingly enough, if press home button minimize app , click notification of app, opens lockscreenactivity without delay.
i've searched lot solution. here's i've tried out far:
- made broadcast receiver run in separate thread passing handler when registering broadcast receiver
- acquired wakelock in broadcast receiver's
onreceive()
, released inonresume()
of lockscreenactivity - made separate task stack lockscreenactivity specifying different taskaffinity in manifest. i've played lot of combinations of options related activity stack, nothing has helped far.
- instead of launching activity directly, sent intent service launches activity. nothing has worked, unfortunately.
here's manifest declaration of activity, , service:
<activity android:name=".lockscreenactivity" android:label="@string/app_name" android:excludefromrecents="true" android:taskaffinity="@string/task_lockscreen"> </activity> <service android:name=".services.baseservice" android:enabled="true" > </service>
broadcast receiver:
public class screenreceiver extends broadcastreceiver { private static final string log_tag = screenreceiver.class.getsimplename(); private static final string handler_thread_name = "screen_receiver_thread"; public static final string wakelock_tag = "lockscreen_overlay_create_wakelock"; @override public void onreceive(context context, intent intent) { if (intent.getaction().equals(intent.action_screen_off)) { wakelockhelper.acquirewakelock(wakelock_tag, context); log.d(log_tag, "screen off"); context.startservice(baseservice.getserviceintent(context, null, baseservice.action_start_lockscreen_activity)); } else { if (intent.getaction().equals(intent.action_screen_on)) { log.d(log_tag, "screen on"); } } } public static void registerscreenreceiver(context context){ new broadcastreceiverregistration().execute(context); } private static class broadcastreceiverregistration extends asynctask<context, void, void>{ @override protected void doinbackground(context... params) { context context = params[0]; if(utility.checkfornullandwarn(context, log_tag)){ return null; } handlerthread handlerthread = new handlerthread(handler_thread_name); handlerthread.start(); looper looper = handlerthread.getlooper(); //will block till thread started, hence using asynctask handler handler = new handler(looper); intentfilter filter = new intentfilter(intent.action_screen_off); filter.addaction(intent.action_screen_on); broadcastreceiver mreceiver = new screenreceiver(); context.registerreceiver(mreceiver, filter, null, handler); return null; } } }
wakelockhelper class manages wakelocks in app. registerscreenreceiver()
called service when starts.
here's oncreate() of lockscreenactivity:
protected void oncreate(bundle savedinstancestate) { log.d(log_tag, "lockscreenactivity oncreate()"); super.oncreate(savedinstancestate); setcontentview(r.layout.activity_lock_screen); if (savedinstancestate == null) { getfragmentmanager().begintransaction() .add(r.id.container, new lockscreenfragment()) .commit(); } getwindow().addflags(windowmanager.layoutparams.flag_dim_behind); getwindow().setdimamount((float) 0.4); getwindow().addflags(windowmanager.layoutparams.flag_show_when_locked); int systemuivisibilityflags = view.system_ui_flag_hide_navigation | view.system_ui_flag_fullscreen | view.system_ui_flag_layout_hide_navigation | view.system_ui_flag_layout_fullscreen; if(build.version.sdk_int >= build.version_codes.kitkat) { systemuivisibilityflags = systemuivisibilityflags | view.system_ui_flag_immersive_sticky; } getwindow().getdecorview().setsystemuivisibility(systemuivisibilityflags); }
here's log when things work expected: (screen intially on; turned off , on again)
09-19 11:00:09.384 31226-31243/com.pvsagar.smartlockscreen d/screenreceiver﹕ screen off 09-19 11:00:09.384 31226-31226/com.pvsagar.smartlockscreen d/baseservice﹕ starting lockscreen overlay. 09-19 11:00:09.394 31226-31226/com.pvsagar.smartlockscreen d/lockscreenactivity﹕ lockscreenactivity oncreate() 09-19 11:00:09.735 31226-31243/com.pvsagar.smartlockscreen d/screenreceiver﹕ screen on
not delay between screen off , sending intent , lockscreenactivity starting. screen on; press home app (any app, other activity of own app); screen turned off , on again:
09-19 11:02:51.557 31226-31243/com.pvsagar.smartlockscreen d/screenreceiver﹕ screen off 09-19 11:02:51.557 31226-31226/com.pvsagar.smartlockscreen d/baseservice﹕ starting lockscreen overlay. 09-19 11:02:51.708 31226-31243/com.pvsagar.smartlockscreen d/screenreceiver﹕ screen on 09-19 11:02:54.851 31226-31226/com.pvsagar.smartlockscreen d/lockscreenactivity﹕ lockscreenactivity oncreate()
here, can see, screen off broadcast received in time, service gets intent , send intent lockscreenactivity, oncreate() of lockscreenactivity delayed 3 seconds.
this how lockscreenactivity started service:
intent lockscreenintent = new intent(this, lockscreenactivity.class); lockscreenintent.addflags(intent.flag_activity_new_task); log.d(log_tag, "starting lockscreen overlay."); startactivity(lockscreenintent);
this pending intent passed notification (just show same thing):
intent notificationintent = new intent(context, lockscreenactivity.class); notificationintent.addflags(intent.flag_activity_new_task); pendingintent pendingintent = pendingintent.getactivity(context, 0, notificationintent, 0); notificationbuilder.setcontentintent(pendingintent);
i'm not having idea why happening. gc not running much. problem? can possibly overcome this? suggestions/ideas appreciated.
the entire code can found at: https://github.com/aravindsagar/smartlockscreen/tree/backend_code_strengthening
after digging, found out cause of problem. apparently it's not bug, feature not allow services or broadcastreceivers launch activities 5 seconds after home button pressed. no easy way overcome this.
more info here: https://code.google.com/p/android/issues/detail?id=4536
i replaced activity window added window manager of running service. not cause delay.
Comments
Post a Comment