安卓11之adb命令清除锁屏密码
需求說明
客戶設置密碼后容易遺忘,反復刷機不符合需求,需要預留一個adb命令去直接清除掉鎖屏密碼。
為什么不直接刪除對應文件
安卓11找不到對應的.key文件了,根據老的版本,大概8.0之前是有.key文件去管理鎖屏密碼的,但是現在沒有了
修改
原理
制造假數據(空的數據)去覆蓋掉,然后在通過方法去清除掉空數據
設置假數據去覆蓋掉舊的密碼
路徑:
frameworks\base\core\java\com\android\internal\widget\LockPatternUtils.java代碼:
/*** Save a new lockscreen credential.** <p> This method will fail (returning {@code false}) if the previously saved credential* provided is incorrect, or if the lockscreen verification is still being throttled.** @param newCredential The new credential to save* @param savedCredential The current credential* @param userHandle the user whose lockscreen credential is to be changed** @return whether this method saved the new password successfully or not. This flow will fail* and return false if the given credential is wrong.* @throws RuntimeException if password change encountered an unrecoverable error.* @throws UnsupportedOperationException secure lockscreen is not supported on this device.* @throws IllegalArgumentException if new credential is too short.*/public boolean setLockCredential(@NonNull LockscreenCredential newCredential,@NonNull LockscreenCredential savedCredential, int userHandle) {if (!hasSecureLockScreen()) {throw new UnsupportedOperationException("This operation requires the lock screen feature.");}newCredential.checkLength();try {if (!getLockSettings().setLockCredential(newCredential, savedCredential, userHandle)) {return false;}} catch (RemoteException e) {throw new RuntimeException("Unable to save lock password", e);}onPostPasswordChanged(newCredential, userHandle);return true;}這個類怎么用吶?
直接百度翻譯注釋:
這個方法是用來保存新的鎖屏憑證
這個方法有三個參數,分別代表:
新的鎖屏憑證,舊的鎖屏憑證,要修改憑證的用戶
這里提到了LockscreenCredential這個類,前面兩個參數是基于這個修改的
路徑:
frameworks\base\core\java\com\android\internal\widget\LockscreenCredential.java新的鎖屏憑證:
這里我們需要的是一個空的密碼憑證,對應方法為:
/*** Creates a LockscreenCredential object representing empty password.*/public static LockscreenCredential createNone() {return new LockscreenCredential(CREDENTIAL_TYPE_NONE, new byte[0]);}很好,這里調用了自身的構造方法,返回一個基于自己的對象,這個構造方法怎么說
百度翻譯注釋結果:
創建表示給定模式的LockscreenCredential對象
第一個參數是一個類似標識符的東西,在這個類中通過對應標識去做不同的事情
看代碼得知后面的參數是指這個的存放的長度,就相當于預留多少內存空間去存放,這里createNone給的是new byte[0],走if上面,不細究,喜歡看的自己去細看源碼。
這樣我們就大概可以知道直接LockscreenCredential.createNone()就可以拿到一個新的空的鎖屏憑證了,(這里注一個小知識:被static修飾的方法可以直接調用,不需要new對象,且只能被繼承,不能被重寫)。
舊的鎖屏憑證
舊的鎖屏憑證這個就比較麻煩了,主要是有三種(除了無和滑動),這三種分別代表圖案,PIN碼和密碼。
回到LockscreenCredential這個類,先說密碼的鎖屏憑證
首先是空的憑證和非空憑證的判斷,接下來找非空的判斷走法
/*** Creates a LockscreenCredential object representing the given alphabetic password.*/public static LockscreenCredential createPassword(@NonNull CharSequence password) {return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD,charSequenceToByteArray(password));}傳個密碼就好了。嗯,當然,這就要知道安卓系統一般保存這種數據都是通過數據庫的,既然可以寫入,自然就可以拿到了,當然,如果沒有怎么辦,我們就自己做一個。
先拿密碼和PIN碼為例
路徑:
沒有這個路徑怎么辦,老辦法找對應類就好了
Settings.System.putString(getContext().getContentResolver(), "lock_password", passwordText.toString());這句代碼加在handleNext();方法里面,
為什么??
看調用:
這里干了啥,點擊按鍵的監聽,什么按鍵?
很顯然,FooterButton,這里是通過導包拿的,應該是自定義的一個控件,主要說明,為什么在這里面調用,這個就是輸入密碼的時候的下一步按鈕的事件監聽;
好了,這里我們還需要導包
這里我們已經加上了在輸入密碼和PIN碼的,接下來就是圖案密碼了
byte[] pBytes = LockPatternUtils.patternToByteArray(pattern);String res = new String(pBytes);Settings.System.putString(getContext().getContentResolver(), "lock_password", res.toString());加在onPatternDetected(List<LockPatternView.Cell> pattern);方法里面,這里也需要導包
和上面的密碼和PIN碼導的包一樣
由于這兩個類都是Activity,這樣我們需要考慮到這個值是否會受到生命周期的影響,比如說在切換橫豎屏的時候,由于這個值不是固定的xml文件中的存在,且沒有對應id去控制,所以,我們需要在onSaveInstanceState()中去保存
這樣我們就創建好了一個舊的密碼的存儲方式,且保存了舊的憑證的臨時數據。
我們可以通過下面的方式拿到密碼,且知道圖案密碼的保存值也是被轉化的password
這樣就可以拿到舊的鎖屏憑證之密碼憑證了。
PIN碼的拿法和這個一致,只是方法里面的參數換成了CharSequence pin
我們拿到密碼是針對鎖屏所有的,所以傳入的參數還是password,只是方法換成了
接下來就是圖案密碼了
/*** Creates a LockscreenCredential object representing the given pattern.*/public static LockscreenCredential createPattern(@NonNull List<LockPatternView.Cell> pattern) {return new LockscreenCredential(CREDENTIAL_TYPE_PATTERN,LockPatternUtils.patternToByteArray(pattern));}這里用同樣的方法去將password轉化成需要的參數。
這里需要借助LockPatternUtils的byteArrayToPattern()方法,先將password轉化成byte數組,以byte數組轉化成pattern,最后通過createPattern()方法拿到舊的鎖屏憑證之圖案。
要修改憑證的用戶
int userId = UserHandle.USER_SYSTEM;這里直接拿系統用戶就可以了
這個是UserHandle的類,由于文章篇幅過長,不做闡述,自己去看詳細代碼
http://t.csdn.cn/2KVw0
現在就已經完成了新的空密碼替換舊的密碼了,我們還需要讓鎖屏界面不顯示,也就是切換成無的狀態
這里用的是LockPatternUtils的setLockScreenDisabled(boolean disable, int userId);方法
以下就是清除鎖屏密碼的全部代碼
//清除鎖屏密碼public void clearLockscreen(){String password = Settings.System.getString(mContext.getContentResolver(), "lock_password");int userId = UserHandle.USER_SYSTEM;int type = mLockPatternUtils.getCredentialTypeForUser(userId);if(type == LockPatternUtils.CREDENTIAL_TYPE_PASSWORD){mLockPatternUtils.setLockCredential(LockscreenCredential.createNone(),LockscreenCredential.createPasswordOrNone(password), userId);mLockPatternUtils.setLockScreenDisabled(true, userId);ShutdownThread.reboot(mContext,"userrequested",false);}else if(type == LockPatternUtils.CREDENTIAL_TYPE_PIN){mLockPatternUtils.setLockCredential(LockscreenCredential.createNone(),LockscreenCredential.createPinOrNone(password), userId);mLockPatternUtils.setLockScreenDisabled(true, userId);ShutdownThread.reboot(mContext,"userrequested",false);}else if(type == LockPatternUtils.CREDENTIAL_TYPE_PATTERN){byte[] pBytes = password.getBytes();mLockPatternUtils.setLockCredential(LockscreenCredential.createNone(),LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(pBytes)), userId);mLockPatternUtils.setLockScreenDisabled(true, userId);ShutdownThread.reboot(mContext,"userrequested",false);}}這里用了ShutdownThread的reboot方法,這個方法是為了請求干凈關機,等待子系統清理其
*狀態等,必須從其UI所在的循環器線程調用。如果不使用這個方法會無效。
而type是為了篩選3種不同的密碼實現方式。
方法已經給了,則adb命令可以通過廣播去實現,這里不做具體闡述,注意在導包的時候可能由于不處在一個項目里面而失敗,建議在PhoneWindowManager.java中實現。
總結
以上是生活随笔為你收集整理的安卓11之adb命令清除锁屏密码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html弹性盒子垂直排列,css3弹性盒
- 下一篇: RTCP Interarrival j