views:

546

answers:

1

Hi,

I was wondering if anyone understood how to make your application be displayed when you unlock the screen. I have an application where the user turns on a Bluetooth device, it connects to the phone, and the user should be presented with a UI. Having them hunt for the app or using the notification menu is not a workable option (too much work and not the obvious behavior).

The problem is that: When the screen is unlocked: - you can popup the activity from the background service when Bluetooth connects to a device - User is happy because the UI is right there

When the screen is locked: - The application gets started but is destroyed - User unlocks the phone and nothing is there but the homescreen

One work around would be to disable the keyguard when the application gets woken up but the nuclear option is a pretty bad option.

PS: I know the standard Android assumption is that you shouldn't do this. In the normal case this behavior is fine, but in this case I explicitly did something I want the phone to respond without adding more work for the user to do. As per Google's guidelines if you don't like this behavior there can be an option for you to turn this off or you can not use the application.


A few more details, so after looking at this a bit more the problem isn't necessarily that you can't have an activity running when the screen is locked, unlock and expect it to be waiting. That does work if you do something like the following:

  • lock your device
  • run an app through Eclipse while the phone is locked/off
  • unlock and it will be waiting for you

But in the case the Activity is already running and I'm brining up a new window (which happens to be a transparent one, saying you're connected and asking what they want to do). The problem is that it gets killed

E/BackgroundPOPUP( 2436): POPUP created via onCreate!
I/UsageStats(   78): Unexpected resume of com.test.POPUP while already resumed in com.android.launcher2
E/BackgroundPOPUP( 2436): POPUP onPause
E/MyBacgrkoundService( 2436): POPUP active!
I/ActivityManager(   78): Displayed activity com.test.POPUP/.PopupTest: 175 ms (total 175 ms)
I/UsageStats(   78): Something wrong here, didn't expect com.android.launcher2 to be paused
E/BackgroundPOPUP( 2436): POPUP has ended through a call to onStop
E/BackgroundPOPUP( 2436): POPUP has ended through a call to onDestroy

The setup here is as follows:

  • MyBackgroundService is a serivce that handles Bluetooth state (waits for connections, turns on Bluetooth if the user starts the app, etc.). It triggers a popup BackgroundPOPUP activity that runs a ViewFlipper. MyBackgroundService starts BackgroundPOPUP through an intent.
  • BackgroundPOPUP is an activity with a Translucent theme (Theme.Translucent to be precise), it shows a ViewFlipper with some instructions and presents some options
A: 

You can use the KeyGuardManager method public void exitKeyguardSecurely (KeyguardManager.OnKeyguardExitResult callback)

Exit the keyguard securely. The use case for this api is that, after disabling the keyguard, your app, which was granted permission to disable the keyguard and show a limited amount of information deemed safe without the user getting past the keyguard, needs to navigate to something that is not safe to view without getting past the keyguard. This will, if the keyguard is secure, bring up the unlock screen of the keyguard. Parameters callback Let's you know whether the operation was succesful and it is safe to launch anything that would normally be considered safe once the user has gotten past the keyguard.

I'm not 100% sure that this fits what you want to do.

Another option is to check if the keyguard is on when your app is waking up using public boolean inKeyguardRestrictedInputMode () and if it is stop your app from waking up until the keyguard is unlocked

Donal Rafferty
Thanks! I wasn't aware of the inKeyguardRestrictedInputMode(), that helps. I added a bit more detail above, so I'd like to be able to have the activity window waiting for the user when they use it but it just seems to be getting killed. I was thinking you couldn't do this at all with an activity, but it does seem to work when you newly create a process. This might actually be because it is a transparent window so I'll check on that. Android seems to treat them quite differently in some cases so maybe that's the real problem.
Dave
After playing with this for a bit, I wasn't able to find something that worked in a naive way. i.e. you say 'startActivity' and independent of whether the screen was on/locked/off the user would see the activity (maybe when they unlocked the screen).The activity would get destroyed if the screen was off/locked so what I did was trigger a static method that checks if the keyguard is enabled. If it is it waits until the user unlocks the screen to send the startActivity intent. Right now I'm using a timer but I'll switch to ACTION_USER_PRESENT in a bit.
Dave