客户需求:
客户自定义的第三方锁屏APK出现时,需要屏蔽掉Home和RecentApp键,防止用户强制退出锁屏运用。
解决方法:
利用系统的Activity栈来解决。当我们看到当前出现在界面的Activity时,此时改Activity是处于Activity栈的栈顶的。我们可以判断当前栈顶的Activity是不是我们的锁屏运用,如果是的话就在Home和RecentApp按键处将事件捕捉。
获取Activity栈顶的Activity包名:
private boolean getTopApp(Context context, String appPackgeName) {
String topAppPackgeName = "";
boolean isTop = false;
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runingTaskS = am.getRunningTasks(1);
if (runingTaskS != null && !runingTaskS.isEmpty()) {
ActivityManager.RunningTaskInfo taskInfo = runingTaskS.get(0);
topAppPackgeName = taskInfo.topActivity.getPackageName();
if (appPackgeName.equals(topAppPackgeName)) {
return true;
}
}
return false;
}
具体该在哪里调用getTopApp方法呢?
具体位置类:PhoneWindowManager.java
具体源码路径:( / 代表源码根目录)
/system/frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
具体方法:屏蔽Home键所在方法,launchHomeFromHotKey:
void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {
// by tlh 2016.08.12 start
if(getTopApp()){return;}
// by tlh 2016.08.12 end
if (respectKeyguard) {
if (isKeyguardShowingAndNotOccluded()) {
// don't launch home if keyguard showing
return;
}
if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
// before launching home
mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@Override
public void onKeyguardExitResult(boolean success) {
if (success) {
try {
ActivityManagerNative.getDefault().stopAppSwitches();
} catch (RemoteException e) {
}
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
}
}
});
return;
}
}
屏蔽RecentApp键方法,在interceptKeyBeforeDispatching方法中添加一条判断的分支,如下:
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
String lockApp = "com.celltick.lockscreen.LockerActivity";
getTopApp();
if (<span style="color:#0b050;">get</span>TopApp(context,lockApp)) {
return -1;
}
* 如果上面的方法RecentApp按钮没有起到我们预期的效果,Android5.0和Android6.0参照如下方法:
Android5.0在
/system/frameworks/base/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java类中的startAlternateRecentsActivity方法中调用getTopApp方法。
Android6.0在
/system/frameworks/base/packages/SystemUI/src/com/android/systemui/recents/Recents.java类中的startAlternateRecentsActivity方法中调用getTopApp方法。
最后,如果是客户锁屏运用的话,就要将系统的锁屏运用去除:
/system/frameworks/base/packages/SettingsProvider/res/values/defaults.xml文件中的
<bool name="def_lockscreen_disabled">true</bool> disable掉。