我们都知道在安卓设备与pc连接时间有 charge only、mtp、ptp等几个模式。其中charge only只是充电,mtp即可充电也可以传输数据,ptp只能传输照片视频一类的数据。有些客户要求手机默认是MTP模式,所以这里就产生了一个设计上的遗漏,就是连接pc时间如果有密码(密码、图案及pin码)锁屏状态,客户认为这时间应该处于保密状态,就不能显示有盘符,不能传输数据。所以就做了这个在有密码锁屏状态停止mtp。
要实现这个功能,需要注意一下几点:1、解锁与锁屏的状态;2、解锁与锁屏的状态;3、mtp的连接与断开;4、当前的解锁方式
说了以上这些,接下来直接贴代码:
·1、有关解锁与锁屏的代码,设计的文件是:frameworks/base/packages/SystemUI/src/com/Android/systemui/keyguard/KeyguardViewMediator.Java
a) 、isHavePasswordLock()判断当前锁屏方式是不是需要停止mtp,这里在有密码、图案、pin码时间返回true,需要停止mtp,其他时间均不作处理。
private boolean isHavePasswordLock(){
//if (why != 2 && why != 3) return false;
if (mLockPatternUtils == null)
mLockPatternUtils = new LockPatternUtils(mContext);
int security = mLockPatternUtils.getActivePasswordQuality(KeyguardUpdateMonitor.getCurrentUser());
Log.d("cjf_tag","mLockPatternUtils ---------security = "+security);
switch (security) {
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
return true;
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
return true;
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
return true;
case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
return false;
}
return false;
}b)、锁屏时间会调用onStartedGoingToSleep(int why)方法,在该方法里面添加一个广播
if (isHavePasswordLock()&&(why == 2 || why == 3)){
mContext.sendBroadcast(new Intent(Intent.ACTION_KEYGUARD_LOCK));
}why=2 :power键引起的锁屏 why=3 时间到系统自动进入锁屏
在锁定时间并且是有密码、图案后者pin码时间才会发出广播
c)、解锁动作的方法是keyguardDone() 在该方法里面发送解锁动作的广播
mContext.sendBroadcast(new Intent(Intent.ACTION_KEYGUARD_UNLOCK));
d)、在显示锁屏界面时间保存当前锁屏方式(是否需要停止或者开启mtp,主要是应对在未连接pc时间,设备更换了锁屏方式,从新连接pc但是未解锁,判断是否需要继续或者停止mtp),显示锁屏界面的方法 showLocked(),在该方法里面记录状态
if (isHavePasswordLock()){
Log.d(TAG,"showLocked isHavePasswordLock() = true");
Settings.System.putInt(mContext.getContentResolver(),Intent.ACTION_KEYGUARD_LOCK,1);
}else{
Log.d(TAG,"showLocked isHavePasswordLock() = false");
Settings.System.putInt(mContext.getContentResolver(),Intent.ACTION_KEYGUARD_LOCK,0);
}2、mtp模式正常连接时间是通过启动MtpService来加载mtp。涉及文件:packages/providers/MediaProvider/src/com/android/providers/media/MtpService.java
在这里需要知道两个方法:addStorageLocked(volume);mtp模式下添加磁盘显示,就是可以进行数据传输;removeStorageLocked(volume);mtp模式移除在pc端的磁盘显示,不允许数据的传输。
在MtpService中的广播接受器mLocaleChangedReceiver添加需要停止mtp的解锁与锁屏的广播 mIntentFilter.addAction(Intent.ACTION_KEYGUARD_LOCK);
mIntentFilter.addAction(Intent.ACTION_KEYGUARD_UNLOCK);if (Intent.ACTION_KEYGUARD_UNLOCK.equals(action)){
Settings.System.putInt(getApplicationContext().getContentResolver(),Intent.ACTION_KEYGUARD_LOCK,0);
StorageVolume[] volumes = mStorageManager.getVolumeList();
for (int i = 0; i < volumes.length; i++) {
StorageVolume volume = volumes[i];
addStorageLocked(volume);
}
}else if (Intent.ACTION_KEYGUARD_LOCK.equals(action)){
StorageVolume[] volumes = mStorageManager.getVolumeList();
for (int i = 0; i < volumes.length; i++) {
StorageVolume volume = volumes[i];
removeStorageLocked(volume);
}
}这里需要注意的是需要编译每一个存储器(有SD卡情况),还有在接收到解锁广播时间需要将KeyguardViewMediator.java里面的当前解锁状态值Intent.ACTION_KEYGUARD_LOCK还原。
在addStorageLocked方法加上是否锁屏状态,如果是有密码锁屏,直接返回,不在显示磁盘
//读取KeyguardViewMediator.java里面保存的解锁方式
int isHavePasswordLock = Settings.System.getInt(getApplicationContext().getContentResolver(),Intent.ACTION_KEYGUARD_LOCK,0);
KeyguardManager mKeyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
//读取当前是否锁屏
boolean screenlock = mKeyguardManager.inKeyguardRestrictedInputMode();
Log.d(TAG,"isHavePasswordLock = "+isHavePasswordLock+" ......screenlock = "+screenlock);
if (isHavePasswordLock == 1 && screenlock){
return;
}
说明:由于客户要求滑动解锁不算有密码,但是在安卓系统里面滑动解锁也算是有锁状态,所以这里有交叉判断,有点麻烦,不然就只需要在锁屏和解锁给出广播即可,就不用这么多判断了。
到此该功能就算修改完成,仅仅是个人的理解,有更好的方法,欢迎指正和交流。