After calling disableKeyguard() activity enters onPause()

Put your problem here if it does not fit any of the other categories.

After calling disableKeyguard() activity enters onPause()

Postby Pr0v0dn1k » Tue Nov 17, 2009 5:15 pm

I have an activity that is being called from remote service. I would like to implement the following logics: when the activity is in foreground, prevent screen lock, if the screen lock is already set - unlock, when the activity goes to background - return lock to initial state.

There are two methods disableKeyguard() and enableKeyguard() that operates the keyguard state. According to the desired logics they should be called from onResume() and from onPause() (as recommended in docs). If no lock is set everything works fine. But if the screen is locked before starting the activity, it enters the following methods:
    onCreate()
    onResume()
    disableKeyguard()
    onPause()
that is not expected.
It does not work because when activity calls onPause() after disabling Keyguard it's being reanabled and the screen lock screen appears. If I comment enableKeyguard() in onPause() the activity is displayed on the screen correctly and any input event returns the activity to onResume().
Moving the enableKeyguard() to onStop() solves the problem but the situation when the activity goes to background and is still not stopped is not handled.

Here is a simplified activity code:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public class TestActivity extends Activity {
  2.  
  3.         private KeyguardManager.KeyguardLock mKeyguardLock = null;
  4.  
  5.         protected void onCreate(Bundle savedInstanceState) {
  6.                 super.onCreate(savedInstanceState);
  7.                 // init UI ...
  8.                
  9.         }
  10.  
  11.         protected void onPause() {
  12.                 super.onPause();
  13.                 enableKeyguard(); //
  14.         }
  15.  
  16.         protected void onResume() {
  17.                 super.onResume();
  18.                 disableKeyguard();
  19.         }
  20.  
  21.         protected void disableKeyguard() {
  22.                 if (mKeyguardLock == null) {
  23.                         KeyguardManager keyboardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
  24.                         mKeyguardLock = keyboardManager.newKeyguardLock(TAG);
  25.                 }
  26.                 mKeyguardLock.disableKeyguard();
  27.         }
  28.  
  29.         protected void enableKeyguard() {
  30.                 if (mKeyguardLock != null) {
  31.                         mKeyguardLock.reenableKeyguard();
  32.                         mKeyguardLock = null;
  33.                 }
  34.         }
  35. }
  36.  
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


Any ideas what's wrong?
Pr0v0dn1k
Freshman
Freshman
 
Posts: 6
Joined: Sun Nov 08, 2009 4:11 pm

Top

Postby i4nc4mp » Fri Jan 01, 2010 1:45 am

Interesting. I am also experiencing a very strange behavior quirk with the keyguard disable commands.

I am not certain what exactly is going wrong for you. I thought we could compare what we are doing to see if something related is wrong. I am calling disable and re-enable from a remote service that has the screen on and off receivers. So I want to to do the reverse of what you are doing, call an activity up when the user wakes the device, and that activity gets called from the remote service of course, so perhaps we are taking similar approaches after all.

All I do is respond to screen on with disable keyguard, and screen off with reenable. The only problem with this is that when I do it, there is a bug afterward that the home long press won't respond correctly. Its only a minor impact to this method, because after I try once, the screen flickers, and home app launches, and after that the long press will respond.... But when I change the method to try to disable keyguard at screen OFF, then call up the activity and release the wakelock immediately (so I can let that activity do things immediately when the screen is next awakened) then my keyguard disabling actually fails from then on. It doesn't seem to matter whether I do the disable from screen off or on. If I don't deliberately re-enable at screen off, this happens. In other words, the next screen off that happens after i use the home button at all will cause the keyguard to come back, and no further disable calls will work whatsoever. This seems almost identical to your issue in which the keyguard decides to come back inexplicably and then can't be disabled. Does a remote service do an onPause? I am still learning the ins and outs of the lifecycle and this app is my first attempt at android.

Here is some code, first the remote service code that doesn't experience the total failure:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. @Override
  2.  
  3.         public void onStart(Intent intent, int startId) {
  4.  
  5.                 super.onStart(intent, startId);
  6.  
  7.                 //serviceHandler = new Handler();
  8.  
  9.                 //serviceHandler.postDelayed(myTask, 1000L);
  10.  
  11.                 Log.d(getClass().getSimpleName(), "onStart()");
  12.  
  13.                
  14.  
  15.                 //register the receivers
  16.  
  17.                 IntentFilter onfilter = new IntentFilter (Intent.ACTION_SCREEN_ON);
  18.  
  19.         IntentFilter offfilter = new IntentFilter (Intent.ACTION_SCREEN_OFF);
  20.  
  21.         registerReceiver(skip, onfilter);
  22.  
  23.         registerReceiver(guard, offfilter);
  24.  
  25.         }
  26.  
  27.  
  28.  
  29. private boolean KG()
  30.  
  31.         {
  32.  
  33.                 ManageKeyguard.initialize(getApplicationContext());
  34.  
  35.  
  36.  
  37.         if (ManageKeyguard.inKeyguardRestrictedInputMode()) return true;
  38.  
  39.         else return false;
  40.  
  41.                
  42.  
  43.         }
  44.  
  45.        
  46.  
  47.         BroadcastReceiver skip = new BroadcastReceiver() {
  48.  
  49.                
  50.  
  51.                 public static final String TAG = "skipKeyguard";
  52.  
  53.                 public static final String Screen = "android.intent.action.SCREEN_ON";
  54.  
  55.  
  56.  
  57.                 @Override
  58.  
  59.                 public void onReceive(Context context, Intent intent) {
  60.  
  61.                         if (!intent.getAction().equals(Screen)) return;
  62.  
  63.                        
  64.  
  65.                         Log.v(TAG, "Screen just went ON!");//marks that we received the broadcast
  66.  
  67.                        
  68.  
  69.                         if (KG()) {
  70.  
  71.  
  72.  
  73.                               if (!NeedToGuard) {
  74.  
  75.                                   /**
  76.  
  77.                                   ManageKeyguard.exitKeyguardSecurely(new LaunchOnKeyguardExit() {
  78.  
  79.                                         public void LaunchOnKeyguardExitSuccess() {
  80.  
  81.                                   NeedToGuard = true;}});
  82.  
  83.                                   }*/
  84.  
  85.                                   ManageKeyguard.disableKeyguard(context);
  86.  
  87.                                   NeedToGuard = true;
  88.  
  89.                         }      
  90.  
  91.                         else {
  92.  
  93.                               Log.v(TAG, "Skip apparently got requested when no KG was up");
  94.  
  95.                             }
  96.  
  97.                         }}
  98.  
  99.                          
  100.  
  101.         };
  102.  
  103.        
  104.  
  105.         BroadcastReceiver guard = new BroadcastReceiver() {
  106.  
  107.        
  108.  
  109.         public static final String TAG = "reguard";
  110.  
  111.         public static final String Screenoff = "android.intent.action.SCREEN_OFF";
  112.  
  113.  
  114.  
  115.         @Override
  116.  
  117.         public void onReceive(Context context, Intent intent) {
  118.  
  119.                 if (!intent.getAction().equals(Screenoff)) return;
  120.  
  121.                
  122.  
  123.                 Log.v(TAG, "Screen just went OFF");
  124.  
  125.                
  126.  
  127.                 if (!NeedToGuard) {
  128.  
  129.                                 Log.v(TAG, "re-guard got called, first KG since init");
  130.  
  131.                                 return;
  132.  
  133.                         }
  134.  
  135.                 ManageKeyguard.reenableKeyguard();
  136.  
  137.                 NeedToGuard = false;
  138.  
  139.                 }
  140.  
  141. };
  142.  
  143.  
Parsed in 0.041 seconds, using GeSHi 1.0.8.4


The managekeyguard is just a class that handles getting the KM/KL instances

Now here is the modified off receiver which will work flawlessly until I try to use the home button

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. BroadcastReceiver guard = new BroadcastReceiver() {
  3.  
  4.        
  5.  
  6.         public static final String TAG = "reguard";
  7.  
  8.         public static final String Screenoff = "android.intent.action.SCREEN_OFF";
  9.  
  10.  
  11.  
  12.         @Override
  13.  
  14.         public void onReceive(Context context, Intent intent) {
  15.  
  16.                 if (!intent.getAction().equals(Screenoff)) return;
  17.  
  18.                
  19.  
  20.                 Log.v(TAG, "Screen just went OFF");
  21.  
  22.                 if (!skipComplete) {
  23.  
  24.                 ManageWakeLock.acquireFull(context);
  25.  
  26.                 //Step 1: Turn the screen BACK ON while disabling KG (happens in the full Wake)
  27.  
  28.                 //Step 2: Cancel it back in 100 milisecond
  29.  
  30.                 ManageWakeLock.DoCancel(context,1);
  31.  
  32.                 skipComplete = true;
  33.  
  34.                 }
  35.  
  36.                 else {
  37.  
  38.                         Log.v(TAG,"skip is now complete, resetting");
  39.  
  40.                         skipComplete = false;
  41.  
  42.                 //broadcast tries a 2nd time when our short wakelock ends
  43.  
  44.                 //this just gets it ready to fire again next time screen goes off.
  45.  
  46.                 }
  47.  
  48. };
  49.  
  50.  
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


This was just to show that it seems to have nothing to do with when you call the skip or how the wakelock is occurring. The same exact bug happens if, for example, I call the disable at screen on & don't call re-enable. Works fine till home button happens, then breaks. Same if I disablekeyguard at the start of the service (happens when my service gets loaded at boot, first thing user sees is the keyguard, then i call the disable automatically, it disappears, and I can go happily on until I want to press the home button). This doesn't make sense to me because I am operating 100% from the remote service.
i4nc4mp
Developer
Developer
 
Posts: 39
Joined: Sat Dec 12, 2009 6:44 pm

Postby i4nc4mp » Sat Jan 02, 2010 6:59 am

I have discovered a fix for this which makes it so you don't have to call disable or re-enable. You can tell your activity to skip the keyguard. I am not sure if this will be a perfect fit for how your activity gets called, but my receiver now just calls up the intent and launches my activity. The activity itself actually then asks the window manager during its oncreate to cut through the keyguard. it works very well, i think that with how the default android lockscreen is programmed it is the best you can get in terms of bypassing it. what I did was ported the source from the alarm alert default app. alarm seems like an example of exactly what you want to do and it happens to work awesome for my screen_on receiver. I will be documenting the source I am using shortly, just taking a break for the day. the AlarmAlert activity source is the important part, view it's onCreate to see what it is doing with the windowmanager to use keyguard skipping flags.
i4nc4mp
Developer
Developer
 
Posts: 39
Joined: Sat Dec 12, 2009 6:44 pm

Postby i4nc4mp » Sat Jan 02, 2010 9:02 pm

okie dokie, here's the oncreate that works the magic:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. @Override
  2.  
  3.     protected void onCreate(Bundle icicle) {
  4.  
  5.         super.onCreate(icicle);
  6.  
  7.  
  8.  
  9.         requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
  10.  
  11.         getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
  12.  
  13.                 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
  14.  
  15.                 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
  16.  
  17.                 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
  18.  
  19.         updateLayout();
  20.  
  21.         }
  22.  
  23.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


after this you never need to call reenablekeyguard. it just happens at screen off at the normal time.
this is what the AlarmAlert does to wake the device, the rest of its code merely just places a notification so it can vibrate/sound
i4nc4mp
Developer
Developer
 
Posts: 39
Joined: Sat Dec 12, 2009 6:44 pm

Postby i4nc4mp » Mon Jan 04, 2010 10:33 pm

I just discovered another workaround. To do it, don't manually call re-enable. Instead. Call disable, then call a handler that waits 50L. The task it calls does securelyexitkeyguard. At the callback, call re-enable. This tells the OS you are exiting the keyguard and want to stay out of it. If you don't do it like this, your bug happens. The bug essentially exists because the OS actually keeps the lockscreen there hiding out, the only reason it does that is so when password unlock mode is running it can be the gatekeeper to the home button. So when you call securely exit, it tells the gatekeeper it can snooze. When password unlock is active, the user has to enter the password to get that far.

Does this make sense?

I'll edit this with snippets but I have to put together a tutorial because I'm using a class that handles all the keyguard manager interactions.
i4nc4mp
Developer
Developer
 
Posts: 39
Joined: Sat Dec 12, 2009 6:44 pm

Top

Return to Other Coding-Problems

Who is online

Users browsing this forum: Yahoo [Bot] and 11 guests