Как создать активность, которая видна поверх экрана блокировки

Я получаю входящее уведомление C2DM, когда экран заблокирован. Я хотел бы проснуться на экране и отобразить сообщение уведомления поверх экрана блокировки с помощью Activity. Я запускаю уведомление из моего C2DM BroadcastReceiver следующим образом:

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 );

и в методе Activity onCreate, я просыпаюсь на экране следующим образом:

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();
}

Экран проснулся, но активность уведомления не видна, пока я не разблокирую экран.

Я понимаю, что я могу избежать экрана блокировки с кодом ниже, но это нежелательно. Я хочу, чтобы пользователь разблокировал телефон, только если он/она заинтересован в чтении/ответе на уведомление.

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

Ответ 1

Это невозможно, насколько я знаю. Похоже, вы пытаетесь воспроизвести опыт iOS. Вы должны понимать, что андроид имеет свои собственные соглашения и их нарушение не является чем-то, что вы должны сделать легкомысленно.

Android - это немного противоречие. Он очень открыт, и как разработчик у вас есть доступ ко всему, и это зависит от вас, чтобы использовать эти силы для добра или зла. Когда я говорю "зло", я не имею в виду вредоносное ПО. Я имею в виду приложения, которые пытаются получить симпатичные и использовать вещи способами, которые они не должны были использоваться, например, рассылать уведомления с просьбой использовать приложение больше. Противоречие в том, что на самом деле у вас нет доступа ко всему, есть несколько частей, которые разработчики решили так важны, что приложение не могло с ними столкнуться. Экран блокировки является одной из этих частей. Вы можете заменить свое домашнее приложение все, что хотите, но вам никогда не придется беспокоиться о том, что ваш экран блокировки замены не работает и не позволяет вам получить доступ к вашему телефону.

Даже если бы это было возможно, у вас было бы больше проблем. Каждый экран блокировки отличается, производители могут его настроить и настроить, поэтому у вас нет гарантий, что ваша деятельность не будет препятствовать разблокировке телефона.

Ответ 2

Использование флагов - это правильный способ сделать это, использование диспетчера питания неверно.

Ваши запросы кажутся мне противоречивыми: вы говорите, что хотите, чтобы активность отображалась поверх экрана блокировки (фактически мы этого не делаем, мы скрываем экран блокировки, чтобы можно было видеть активность), а на в то же время вы хотите, чтобы пользователь сначала должен был разблокировать устройство.

Если вы думаете, что хотите, чтобы пользователь увидел уведомление перед тем, как разблокировать устройство, чтобы увидеть вашу активность... Я действительно думаю, что вы этого не хотите. Уведомление очень мало (в строке состояния вверху), а следующее, которое отображается во время публикации, очень кратковременно. Это не будет хорошим опытом для тех, кто слышал их звуковой сигнал или шум, и вытаскивает его, чтобы посмотреть, что происходит.

Вы должны использовать любую комбинацию оконных флагов, которые имеют смысл для вашего приложения. Вы можете получить практически любое разумное поведение между различными комбинациями из них. Они используются для будильника, пользовательского интерфейса входящего вызова и т.д.

Ответ 3

Попробуйте это в своей деятельности

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..

Надеюсь, что это поможет