Block/Disable android 中的状态栏 Tablet/Mobile
Block/Disable Statusbar in android Tablet/Mobile
我看过 Kioware 和 SureLock 应用程序。他们只是阻止平板电脑中的每个控件。我知道重写后退按钮并处理主页和最近的任务选项。
但我不确定他们是如何设法控制系统栏上的设置选项的。设置出现几分之一秒然后消失。同样,向下滑动时出现的手机状态栏需要被阻止。
如果有人对此有想法,请分享。任何 guidance/help 表示赞赏。
您可以尝试使用 WindowManager
在所需位置添加透明 View
(按照 this 示例)。这样,您将拦截 来自用户的任何点击事件。
一定要设置合适的flags/type,因为需要覆盖系统栏:
WindowManager.LayoutParams dismissParams = new WindowManager.LayoutParams(
viewWidth,
viewHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, //you can also try with TYPE_SYSTEM_OVERLAY, TYPE_SYSTEM_ERROR
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSPARENT);
诀窍是添加覆盖在系统栏上的透明自定义视图,这样所有用户交互(如触摸、拖动)都将被自定义视图消耗。
这是一个工作代码:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
statusBarOverlay = new CustomViewGroup(this);
final WindowManager.LayoutParams localLayoutParams =
new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to receive touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height =
(int) (50 * getResources().getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.TRANSPARENT;
windowManager.addView(statusBarOverlay, localLayoutParams);
自定义 ViewGroup
:
public class CustomViewGroup extends ViewGroup {
public CustomViewGroup(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
}
尽管出于多种原因我已将锁定功能分离到不同的应用程序中,但我自己已经为我的应用程序完成了锁定功能。您可以询问更多信息,如果需要,我会把它们放在这里。
终于找到了解决上述问题的方法。 onWindowFocus change 我刚刚关闭了系统生成的对话框,我的问题就解决了。下面是示例代码。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(!hasFocus)
{// Close every kind of system dialog
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
更新:
在移动端屏蔽在屏幕上向下滑动时出现的状态栏使用下面的方法。
private Handler collapseNotificationHandler;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
boolean currentFocus = hasFocus;
if (!hasFocus) {
collapseNow(true,currentFocus);
}
}
public void collapseNow(final boolean shouldCollapse, final boolean currentFocus ) {
// Initialize 'collapseNotificationHandler'
if (collapseNotificationHandler == null) {
collapseNotificationHandler = new Handler();
}
// If window focus has been lost && activity is not in a paused state
// Its a valid check because showing of notification panel
// steals the focus from current activity's window, but does not
// 'pause' the activity
if (!currentFocus && !isPaused) {
// Post a Runnable with some delay - currently set to 50 ms
collapseNotificationHandler.postDelayed(new Runnable() {
@Override
public void run() {
// Use reflection to trigger a method from 'StatusBarManager'
Object statusBarService = getSystemService("statusbar");
Class<?> statusBarManager = null;
try {
statusBarManager = Class.forName("android.app.StatusBarManager");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method collapseStatusBar = null;
try {
// Prior to API 17, the method to call is 'collapse()'
// API 17 onwards, the method to call is `collapsePanels()`
if (Build.VERSION.SDK_INT > 16) {
collapseStatusBar = statusBarManager.getMethod("collapsePanels");
} else {
collapseStatusBar = statusBarManager.getMethod("collapse");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
collapseStatusBar.setAccessible(shouldCollapse);
try {
collapseStatusBar.invoke(statusBarService);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// Check if the window focus has been returned
// If it hasn't been returned, post this Runnable again
// Currently, the delay is 50 ms. You can change this
// value to suit your needs.
if (!currentFocus && !isPaused) {
collapseNotificationHandler.postDelayed(this, 50);
}
}
}, 0);
}
}
"isPaused" 布尔值,当应用程序处于暂停状态时设置为真。
我看过 Kioware 和 SureLock 应用程序。他们只是阻止平板电脑中的每个控件。我知道重写后退按钮并处理主页和最近的任务选项。 但我不确定他们是如何设法控制系统栏上的设置选项的。设置出现几分之一秒然后消失。同样,向下滑动时出现的手机状态栏需要被阻止。
如果有人对此有想法,请分享。任何 guidance/help 表示赞赏。
您可以尝试使用 WindowManager
在所需位置添加透明 View
(按照 this 示例)。这样,您将拦截 来自用户的任何点击事件。
一定要设置合适的flags/type,因为需要覆盖系统栏:
WindowManager.LayoutParams dismissParams = new WindowManager.LayoutParams(
viewWidth,
viewHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, //you can also try with TYPE_SYSTEM_OVERLAY, TYPE_SYSTEM_ERROR
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSPARENT);
诀窍是添加覆盖在系统栏上的透明自定义视图,这样所有用户交互(如触摸、拖动)都将被自定义视图消耗。
这是一个工作代码:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
statusBarOverlay = new CustomViewGroup(this);
final WindowManager.LayoutParams localLayoutParams =
new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to receive touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height =
(int) (50 * getResources().getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.TRANSPARENT;
windowManager.addView(statusBarOverlay, localLayoutParams);
自定义 ViewGroup
:
public class CustomViewGroup extends ViewGroup {
public CustomViewGroup(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
}
尽管出于多种原因我已将锁定功能分离到不同的应用程序中,但我自己已经为我的应用程序完成了锁定功能。您可以询问更多信息,如果需要,我会把它们放在这里。
终于找到了解决上述问题的方法。 onWindowFocus change 我刚刚关闭了系统生成的对话框,我的问题就解决了。下面是示例代码。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(!hasFocus)
{// Close every kind of system dialog
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
更新:
在移动端屏蔽在屏幕上向下滑动时出现的状态栏使用下面的方法。
private Handler collapseNotificationHandler;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
boolean currentFocus = hasFocus;
if (!hasFocus) {
collapseNow(true,currentFocus);
}
}
public void collapseNow(final boolean shouldCollapse, final boolean currentFocus ) {
// Initialize 'collapseNotificationHandler'
if (collapseNotificationHandler == null) {
collapseNotificationHandler = new Handler();
}
// If window focus has been lost && activity is not in a paused state
// Its a valid check because showing of notification panel
// steals the focus from current activity's window, but does not
// 'pause' the activity
if (!currentFocus && !isPaused) {
// Post a Runnable with some delay - currently set to 50 ms
collapseNotificationHandler.postDelayed(new Runnable() {
@Override
public void run() {
// Use reflection to trigger a method from 'StatusBarManager'
Object statusBarService = getSystemService("statusbar");
Class<?> statusBarManager = null;
try {
statusBarManager = Class.forName("android.app.StatusBarManager");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method collapseStatusBar = null;
try {
// Prior to API 17, the method to call is 'collapse()'
// API 17 onwards, the method to call is `collapsePanels()`
if (Build.VERSION.SDK_INT > 16) {
collapseStatusBar = statusBarManager.getMethod("collapsePanels");
} else {
collapseStatusBar = statusBarManager.getMethod("collapse");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
collapseStatusBar.setAccessible(shouldCollapse);
try {
collapseStatusBar.invoke(statusBarService);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// Check if the window focus has been returned
// If it hasn't been returned, post this Runnable again
// Currently, the delay is 50 ms. You can change this
// value to suit your needs.
if (!currentFocus && !isPaused) {
collapseNotificationHandler.postDelayed(this, 50);
}
}
}, 0);
}
}
"isPaused" 布尔值,当应用程序处于暂停状态时设置为真。