2014-02-18 48 views
5

我想控制設備上的啓用/禁用鍵盤鎖。 爲此,我使用Android SDK的DevicePolicyManager和KeyguardLock API。Android - 如何完全禁用鍵盤鎖

下面是我的實現來管理這樣的:

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

}

這對於屏幕的鎖定工作正常,但解鎖fucntionality工作的一些問題: 有時它的工作原理,因爲我想(完全刪除任何類型的鍵盤保護屏),但有時會顯示「解鎖與幻燈片」鍵盤保護屏。

你知道這裏有什麼問題嗎?如何使它工作穩定(至少在所有情況下,要麼顯示「解鎖滑動」或完全移除鍵盤鎖)?

在此先感謝您的幫助。

編輯

只是想指出的是,我的解決方案作品,但問題是,它的工作不穩定(有時完全刪除鍵盤鎖,有時顯示「幻燈片」鍵盤鎖)。 而且我用它不僅僅是在顯示某些活動時禁用鍵盤鎖,而是控制共同設備的鎖定/解鎖,所以我在Service中使用此代碼,因此我不能撥打getWindow().addFlags(..)因爲我沒有窗口應用。

只是想知道或許任何人處理這種不穩定的行爲。

+0

這是什麼LocalStorage類?你是從某種Web框架做到這一點的?另外,你有沒有得到一個工作解決方案?我期待在DPC中實現這一點。 – Keilaron

回答

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); 
4

AFAIK它不是普遍的可能,否則這將是一個重大的安全漏洞。

在非根深蒂固的手機上,您所能做的最多的就是關閉不安全的鍵盤保護程序,或將您的應用程序顯示在安全鍵盤上方。

這裏有一個組合要做到這一點:

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

+0

這隻會是一個標準的應用場景中的違反。如果有人正在處理DPM,他們至少是一個設備管理員應用程序 - 可能仍然是這種情況,但IMO設備所有者應用程序不僅應該*必須*具有此功能。 – Keilaron

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();只適用於服務。

+0

嘿,thnaks的報價,但我已經使用它的服務,它的工作原理。它只是工作不穩定(完全沒有鍵盤保護或「滑動」鍵盤保護),我想知道任何人都可以處理這種行爲。 – kowalski

+0

你只需要解鎖,對吧? 查看上面的代碼(onCreate methond)。例如,您可以創建新的活動,例如DismissLockActivity,並且當您需要關閉鍵盤鎖時,只需開始活動並完成即可。我現在這個醜陋的黑客,但在我的應用程序,這完美的作品。 – dooplaye