【Android】判断前台窗口的方法
2019-12-10 本文已影响0人
风暴小狼
在进行framework开发的时候经常需要监听前台窗口,根据窗口的不同做不同的业务逻辑。
常用的方法有两种:
一. 获取栈顶activity
二. 获取窗口Params
方法一: 获取栈顶activity
通过读取任务栈,获取topActivity。
优点:可以获取当前topActivity的包名类型和其他信息。
缺点:如果是非Activity窗口(如Dialog),则获取不到。
//获取当前Top activity
private void getTopComponentInfo()
{
ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);
if (null != runningTaskInfos)
{
ComponentName topcmpName = runningTaskInfos.get(0).topActivity;
if (null != topcmpName) {
Log.d(TAG, "topActivity pkg : " + topcmpName.getPackageName() + ", class : " + topcmpName.getClassName());
}
}
}
方法二: 获取窗口Params
通过设置窗口window属性,来判断当前窗口类别:
优点:不限于Activity,可以判断view dialog等
缺点:需要对应窗口添加flag
private static final int PRIVATE_FLAG_INTERCEPT_POWER_KEY = 0x20000000;
public Dialog(Context context, int themeResId) {
super(context, themeResId);
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
//设置私有flag,用于判断窗口,比如当前flag=PRIVATE_FLAG_INTERCEPT_POWER_KEY
//eg:如果此窗口在前台,业务逻辑中就要拦截power键
getWindow().addPrivateFlags(PRIVATE_FLAG_INTERCEPT_POWER_KEY);
getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT , ViewGroup.LayoutParams.WRAP_CONTENT);
initDtv();
}
对应PhoneWindowManager.java中读取windowstate,判断是否拦截:
private boolean shouldPassSpecialKeyToUser(WindowState win, int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_POWER:
return handleSpecialKey(win, PRIVATE_FLAG_INTERCEPT_POWER_KEY);
...
...
...
}
return false;
}
private boolean handleSpecialKey(WindowState win, int mask) {
if (win != null) {
WindowManager.LayoutParams lp = win.getAttrs();
if (lp != null) {
//位与运算,判断当前window flag是否是FLAG_INTERCEPT_POWER_KEY
if ((lp.privateFlags & mask) != 0) {
return true;
}
}
}
return false;
}
如果有其他方法,还请留言交流~