6

デバイスでキーガードの有効化/無効化を制御したい。そのために、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

4 に答える 4

5

You need to add this code:

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

Create LockService with:

@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;
    }

Actually, I don't know why, but k1.disableKeyguard(); works only in Service.

于 2014-03-13T07:20:38.120 に答える
4

私の知る限り、それは普遍的に可能ではありません。そうでなければ、これは重大なセキュリティ違反になります.

ルート化されていない電話でできることは、安全でないキーガードを閉じるか、安全なキーガードの上にアプリを表示することだけです。

これを行うためのコンボは次のとおりです。

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

ルート化された電話では、安全なキーガードの削除を試みることができます (ただし、実際に削除される前にデバイスを再起動する必要がある場合があります)。

これがそのためのコンボです(自分で試したことはありませんが、Playストアのいくつかの「電話のロックを解除する」アプリがこのトリックを使用していると確信しています)

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

最初にadbでこれを試すことをお勧めします。また、これに関する詳細情報を含む XDA スレッドがあります: http://forum.xda-developers.com/showthread.php?t=1800799

于 2014-02-18T12:16:39.727 に答える
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);
于 2014-02-18T11:24:18.910 に答える
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);
于 2014-02-18T11:26:32.770 に答える