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");
Предположим, что последнее обходное решение будет работать правильно.
Приветствия