DevicePolicyManager.lockNow(); не выключается, когда параметры безопасности установлены на "Слайд/Нет"

Пользователь ожидает, что мое приложение отключит экран после использования. На данный момент я достигаю этого с правами администратора устройства и DevicePolicyManager.lockNow(), который отлично работает, если для параметров безопасности установлены PIN/Pattern/FaceUnlock и т.д.

Однако, если вы используете Slide/None, приведенная выше команда просто приводит пользователя к главному экрану (или ничего не делает), что понятно, так как ничего не "блокировать". Есть ли способ добиться отключения экрана в такой ситуации? Мое приложение требует SDK >= 16, если это имеет значение.

Итак, я думаю, мой вопрос: как приложение может надежно отключить экран (я не держу wakelock, я использую WindowManager -flags FLAG_TURN_SCREEN_ON в onAttachedToWindow()).

"Поток" моего приложения:
- Активность запускается по желанию, пока экран выключен, отображается над клавиатурой/переключателями на экране с указанными выше флажками
- Пользователь активно отклоняет мою активность, я звоню lockNow() и finish(), и пользователь ожидает, что экран отключится. Если пользователь использует блокировку none/slide, это не работает, и вместо этого отображается рабочий экран пользователя.

Спасибо!

Ответ 1

Я использовал комментарий Деляна для достижения этого:

Если вы запрашиваете WRITE_SETTINGS, вы можете установить таймаут экрана равным 1 секунде - android.provider.Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 1000); Конечно, тогда вы испортите пользовательские настройки, но я не могу понять, как это сделать. Я видел приложения, которые это делают - NoLED - самый яркий пример.

Ответ 2

Для начала см. здесь:

Чтобы управлять этой политикой, администратор устройства должен иметь тег "force-lock" в разделе "uses-policy" его метаданных.

Администратор вызывающего устройства должен запросить USES_POLICY_FORCE_LOCK, чтобы иметь возможность вызвать этот метод; если это не так, исключение безопасности будет быть брошенным.

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

Я слышал несколько раз, что вызов дважды кода DevicePolicyManager.lockNow() сделает трюк и здесь, один из способов сделать это

mDPM = (DevicePolicyManager)getApplicationContext().getSystemService("device_policy");
Handler handlerUI = new Handler();
      handlerUI.postDelayed(new Runnable() {
          @Override
          public void run() {
              mDPM.lockNow();
          }
      }, 200);
      finish();
      mDPM.lockNow();

Здесь я нашел более сложную версию того же:

Android DevicePolicyManager lockNow() problem
public class SMSMessagingActivity extends Activity {
    /** Called when the activity is first created. */

public static DevicePolicyManager mDPM;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);                    

    }

    public static void LockNow(){
        mDPM.lockNow();
    }

}

ComponentName devAdminReceiver; // this would have been declared in your class body
// then in your onCreate
    mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
    devAdminReceiver = new ComponentName(context, deviceAdminReceiver.class);
//then in your onResume

boolean admin = mDPM.isAdminActive(devAdminReceiver);
if (admin)
    mDPM.lockNow();
else Log.i(tag,"Not an admin");

Предположим, что последнее обходное решение будет работать правильно.

Приветствия