Android - 如何完全禁用键盘锁

时间:2014-02-18 11:21:52

标签: android keyguard device-policy-manager

我想控制设备上的启用/禁用键盘锁。 为此,我正在使用Android SDK的DevicePolicyManager和KeyguardLock API。

以下是我的实施方法:

public class DeviceLocker {

private static DeviceLocker instance;

public static synchronized DeviceLocker getInstance(Context context) {
    if(instance==null) {
        instance = new DeviceLocker(context);
    }
    return instance;
}

private Context context;
private KeyguardLock lock;

private DeviceLocker(Context context) {
    this.context = context;
}

public void lock() {
    lock(true);
}

public void lock(boolean lockNow) {
    getLock().reenableKeyguard();
    DevicePolicyManager devicePolicyManager = getDevicePolicyManager();
    if(devicePolicyManager==null) {
        return;
    }
    LocalStorage storage = LocalStorage.from(context);

    boolean result = devicePolicyManager.resetPassword(storage.getPassword(),
            DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);

    if(lockNow) {
        devicePolicyManager.lockNow();
    }
    storage.setDeviceLocked(true);
}

public void unlock() {
    DevicePolicyManager devicePolicyManager = getDevicePolicyManager();
    if(devicePolicyManager==null) {
        return;
    }
    devicePolicyManager.resetPassword("",0);
    getLock().disableKeyguard();
    LocalStorage.from(context).setDeviceLocked(false);
}

private KeyguardLock getLock() {
    if(lock==null){
        KeyguardManager kgManager = (KeyguardManager)context.getSystemService(Activity.KEYGUARD_SERVICE);
        lock = kgManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
    }
    return lock;
}

private DevicePolicyManager getDevicePolicyManager() {
    DevicePolicyManager devicePolicyManager =
        (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
    ComponentName deviceAdmin = new ComponentName(context, WatchGuardDeviceAdminReceiver.class);
    LocalStorage storage = LocalStorage.from(context);
    if(!devicePolicyManager.isAdminActive(deviceAdmin)) {
        return null;
    }
    if(!storage.isPasswordSet()) {
        UIUtils.showMessage(context, R.string.password_not_set);
        return null;
    }
    devicePolicyManager.setPasswordQuality(deviceAdmin,DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);

    return devicePolicyManager;
}

}

关于屏幕锁定它可以正常工作,但解锁功能可以解决一些问题: 有时候它可以按照我想要的方式工作(完全删除任何类型的键盘保护屏幕),但有时会显示“用幻灯片解锁”键盘保护屏幕。

你知道这里有什么问题吗?如何使其稳定工作(至少在所有情况下都显示“解锁滑动”或完全移除键盘锁?)

提前感谢您的帮助。

修改

只是想指出我的解决方案有效,但问题是它工作不稳定(有时会完全删除键盘锁,有时会显示“幻灯片”键盘锁)。 而且我使用它不仅可以在显示某些活动时禁用键盘锁,而且可以共同控制设备的锁定/解锁,因此我在服务中使用此代码,因此我无法调用getWindow().addFlags(..)因为我没有要申请的窗口。

只是想知道是否有人处理过这种不稳定的行为。

4 个答案:

答案 0 :(得分:4)

AFAIK并非普遍存在,否则这将是一次重大的安全漏洞。

在非根电话上,您可以做的最多就是解除非安全键盘锁或将您的应用显示在安全键盘上方。

这是一个组合来做到这一点:

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

在root手机上,您可以尝试删除安全密钥保护(尽管您可能必须在设备实际消失之前重启设备)。

这是一个组合(没有自己尝试过,但我很确定Play Store中有几个“解锁你的手机”应用使用这个技巧)

Runtime.getRuntime().exec("sudo rm /data/system/gesture.key");

我建议您先通过adb尝试这个。另外,这是一个XDA线程,其中包含更多信息:http://forum.xda-developers.com/showthread.php?t=1800799

答案 1 :(得分:3)

您需要添加以下代码:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|WindowManager.LayoutParams.FLAG_FULLSCREEN|
                WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lockscreen);

        startService(new Intent(this,LockService.class).setAction(Intent.ACTION_SCREEN_OFF));
    }

使用以下命令创建LockService:

@Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {

        if(intent == null || intent.getAction() == null)
            return START_NOT_STICKY;

        String action = intent.getAction();

        if(action.equals(ACTION_SCREEN_OFF))
        {
           KeyguardManager.KeyguardLock k1;
           KeyguardManager km =(KeyguardManager)getSystemService(KEYGUARD_SERVICE);
           k1= km.newKeyguardLock("IN");
           k1.disableKeyguard();  
        }

        return START_NOT_STICKY;
    }

实际上我不知道为什么,但k1.disableKeyguard();仅适用于服务。

答案 2 :(得分:1)

KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>

or 

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

答案 3 :(得分:0)

我建议使用窗口标志dismiss_keyguard或show_when_locked,如果你有一个窗口需要在唤醒时立即通过锁屏的顶部。

http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED

你如何使用它如下(在设置布局之前在onCreate中调用)

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);