How do I create an Activity that is visible on top of the lock screen

8.1k views Asked by At

I'm receiving an incoming C2DM notification while the screen is locked. I'd like to wake up the screen and display the notification message on top of the lock screen using an Activity. I'm launching the notification Activity from my C2DM BroadcastReceiver as follows:

Intent new_intent= new Intent().setClass( context, EIAlertDialog.class );           
new_intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP );      
new_intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );      
context.startActivity( new_intent );

and within the notification Activity's onCreate method, I wake up the screen as follows:

PowerManager powerManager= (PowerManager)getSystemService( Context.POWER_SERVICE );
if (!powerManager.isScreenOn()) {
    mWakeLock= powerManager.newWakeLock(
                   PowerManager.FULL_WAKE_LOCK |
                   PowerManager.ACQUIRE_CAUSES_WAKEUP, 
                   "My Tag" )
    mWakeLock.acquire();
}

The screen is woken up, but the notification Activity is not visible until I unlock the screen.

I realize that I can avoid the lock screen with the code below, but that is not desired. I want the user to unlock the phone, only if he/she is interested in reading/responding to the notification.

getWindow().addFlags(
    WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 
);
3

There are 3 answers

2
hackbod On

Uses the flags is the right way to do it, using the power manager is wrong.

Your requests sound conflicting to me: you say you want the activity to appear on top of the lock screen (in fact we don't do that, we hide the lock screen so the activity can be seen), while at the same time you want the user to first have to unlock the device.

If you are thinking you want the user to see a notification before unlocking the device to see your activity... I really think you don't want that. The notification is very small (in the status bar at the top), and the next that is shown while posting it is very transient. This is not going to be a good experience for someone who heard their phone beep or buzz and is pulling it out to see what is going on.

You should use whatever combination of the window flags that make sense for your app. You can get pretty much any reasonable behavior between the various combinations of them. These are used for the alarm clock, incoming call UI, etc.

2
Atif Farrukh On

Try this in your activity

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);

    boolean screenOn = pm.isScreenOn();//check id screen is on

    if(!screenOn){//if not turn it on or wkaeup the screen

        final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Screen On");
        wl.acquire();
        Toast.makeText(getBaseContext(), "This is WAKEUP SCREEN", Toast.LENGTH_SHORT).show();
        Thread timer = new Thread(){
            public void run(){
                try {
                    sleep(5000);
                } catch (InterruptedException e) {
                    // TODO: handle exception
                }finally{
                    wl.release();// release wakelock important
                }
            }
        };
        timer.start();
    }

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);//keep the activity running under lock screen..

Hope this helps

0
num1 On

This is not possible as far as I know. It sounds like you are trying to replicate the iOS experiences. You should realize that android has its own conventions and violating them is not something you should do lightly.

Android is a little bit of a contradiction. It's very open and as a developer you have access to anything, and it's up to you to use those powers for good or evil. When I say evil I don't mean malware. I mean apps that try to get cute and use things in ways they weren't meant to be used, like putting up notifications asking you to use the app more. The contradiction is that you don't actually have access to everything, there are a few parts the developers decided were so important that app couldn't mess with them. The lock screen is one of those parts. You can replace your home app all you want, but you never have to worry about your replacement lock screen failing and preventing you from accessing your phone.

Even if this were possible you would have more problems to deal with. Every lock screen is different, manufacturers can and do customize it so you have no guarantees your activity won't get in the way of unlocking the phone.