Активность с определенной высотой перед экраном блокировки

Я хочу отобразить действие перед экраном блокировки. Я пробовал использовать этот код в своем методе onCreate:

super.onCreate(savedInstanceState);
Window window = getWindow();

window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);        
setContentView(R.layout.test);

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

super.onCreate(savedInstanceState);
Window window = getWindow();

LayoutParams layout = new WindowManager.LayoutParams();
layout.copyFrom(window.getAttributes());
layout.height = 200;

window.setAttributes(layout);
window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);

setContentView(R.layout.test);

Но тогда Активность не видна перед экраном блокировки. Если я разблокирую телефон, активность отображается напрямую. Любые идеи, почему и как я могу это исправить?

EDIT: я думаю, что это как-то связано с плавающим ФЛАГОМ окна. Если этот флаг установлен (а я думаю, что он будет, когда я изменю размер), активность не отображается на экране блокировки. Но это только предположение. Любые идеи или обходной путь, чтобы исправить это?


person Cilenco    schedule 10.08.2013    source источник
comment
Ожидаете ли вы увидеть Lockscreen(частично) за активностью?   -  person Vikram    schedule 14.08.2013
comment
Да, это проблема. Я хочу видеть экран блокировки за действием и, возможно, захочу разблокировать телефон, пока действие находится на экране блокировки (если это возможно)   -  person Cilenco    schedule 14.08.2013
comment
Я надеюсь, что кто-то может помочь вам. Но, скорее всего, это не сработает.   -  person Vikram    schedule 14.08.2013
comment
Я нашел обходной путь (хотя он еще не проверен): KeyguardManager myKeyGuard = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE); myLock = myKeyGuard.newKeyguardLock("tagName"); myLock.disableKeyguard(); - с разрешением в манифесте android.permission.DISABLE_KEYGUARD. Затем в качестве альтернативы попробуйте Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);.   -  person g00dy    schedule 15.08.2013
comment
Спасибо за вашу помощь, но это не то, чего я хочу. Первое решение полностью отключило экран блокировки. Второй показывает активность после того, как я разблокировал телефон, но не перед экраном блокировки. Я действительно хочу видеть экран блокировки за действием и, возможно, захочу разблокировать телефон, пока действие находится на экране блокировки (если это возможно)   -  person Cilenco    schedule 16.08.2013
comment
Вы реализовали getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); ???   -  person Yogesh Tatwal    schedule 19.08.2013
comment
Да у меня это код из строки 4   -  person Cilenco    schedule 19.08.2013
comment
У меня точное требование. И я столкнулся с теми же проблемами, что и вы. Вы нашли какой-нибудь ответ?   -  person Shirish Herwade    schedule 20.05.2014


Ответы (4)


У меня было подобное требование при разработке моего музыкального проигрывателя. Что я наконец сделал для своего виджета экрана блокировки:

  1. Был прозрачный фон для моего виджета экрана блокировки.
  2. добавлена ​​кнопка «Нажмите, чтобы выйти на экран блокировки» внизу макета.
  3. Чтобы создать ощущение коробки, вокруг кнопок добавлена ​​белая рамка.

Вы можете посмотреть на него, загрузив мой музыкальный проигрыватель "Fusion Music Player" из Google Play.

person Sushil    schedule 20.08.2013

Прежде всего сохраните в настройках Keyguard инстанс.

После этого - отключите программно локскрин по умолчанию на телефоне.

Затем реализует Service, которые перехватывают, когда телефон переходит в состояние блокировки.

При SCREEN_ON проверяем активность в стеке, если она есть показать ее, НЕТ - запускаем по singleTask.

Это единственный способ реализовать действие на экране блокировки. Потому что Google отказывается от экранов блокировки макияжа, и любые манипуляции с этими вещами являются взломом.

Вы можете сделать виджет и поместить его на экран блокировки или ниже.

К вашему сведению: погуглите мой замок для Android (источник на code.google.com)

person Community    schedule 20.08.2013

Наконец я добился того же. Не занимайтесь деятельностью, потому что Android не будет отображать экран блокировки за вашей активностью из соображений безопасности, так что для обслуживания.

Ниже приведен мой код в onStartCommand моей службы.

WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

View mView = mInflater.inflate(R.layout.score, null);

WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
        /* | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON */,
        PixelFormat.RGBA_8888);

mWindowManager.addView(mView, mLayoutParams);
person Shirish Herwade    schedule 21.05.2014

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

Это можно сделать, определив пользовательскую тему в файле res/values/styles.xml (изначально показанном на Как создать прозрачную активность на Android?):

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="Theme.Transparent" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:backgroundDimEnabled">false</item>
  </style>
</resources>

Затем добавьте эту тему в объявление манифеста Activity:

android:theme="@style/Theme.Transparent"

Затем вы можете создать макет (R.layout.lockscreen) для этого действия, добавив этот файл XML. Здесь вы указываете высоту в пикселях:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="200px"
        android:centerInParent="true" >

        <include layout="@layout/test" /> <!-- This points to your R.layout.test layout. -->

    </FrameLayout>

</RelativeLayout>

Наконец, просто используйте первый метод, показанный выше, чтобы показать активность:

super.onCreate(savedInstanceState);
Window window = getWindow();

window.addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED);        
setContentView(R.layout.lockscreen);
person Phil    schedule 19.08.2013
comment
Но с помощью этого метода невозможно разблокировать экран, пока видна активность. Или я могу создать что-то, чтобы щелкнуть по активности? - person Cilenco; 19.08.2013
comment
@Cilenco Я мало имел дело с Window и точно не знаю. Тот же вопрос был задан здесь, и ответ на него может сработать. Кроме того, проверьте флаги, перечисленные здесь, которые могут измениться как вставлено окно (выше или ниже мягкого ввода и т. д.). - person Phil; 19.08.2013
comment
@Cilenco, пожалуйста, скажите мне, сработало ли это решение, потому что я устал от этого, и даже в этом случае (исправить высоту) за ним не отображается экран блокировки, а за моей активностью отображается экран запуска. - person Shirish Herwade; 20.05.2014