Dav*_*man 14
在我看来,有两种选择:
选项1:您可以在状态栏上方放置一个窗口以禁用任何触摸或下拉.
选项2:您还可以覆盖OnWindowFocusChanged()方法,以在显示后立即关闭通知面板.
如何:
选项1:在您的活动中定义以下方法(preventStatusBarExpansion)和类(CustomViewGroup).
public static void preventStatusBarExpansion(Context context) {
WindowManager manager = ((WindowManager) context.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE));
Activity activity = (Activity)context;
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 recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
int result = 0;
if (resId > 0) {
result = activity.getResources().getDimensionPixelSize(resId);
}
localLayoutParams.height = result;
localLayoutParams.format = PixelFormat.TRANSPARENT;
customViewGroup view = new customViewGroup(context);
manager.addView(view, localLayoutParams);
}
public static 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) {
Log.v("customViewGroup", "**********Intercepted");
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
并在活动的onCreate方法中调用preventStatusBarExpansion方法.完成!
选项2:首先,将以下权限添加到Androidmanifest.xml文件中:
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
Run Code Online (Sandbox Code Playgroud)
其次,在您的活动中定义以下类范围变量:
// To keep track of activity's window focus
boolean currentFocus;
// To keep track of activity's foreground/background status
boolean isPaused;
Handler collapseNotificationHandler;
Run Code Online (Sandbox Code Playgroud)
第三,重写onWindowFocusChanged(boolean):
@Override
public void onWindowFocusChanged(boolean hasFocus) {
currentFocus = hasFocus;
if (!hasFocus) {
// Method that handles loss of window focus
collapseNow();
}
}
Run Code Online (Sandbox Code Playgroud)
第四,定义collapseNow(); 方法:
public void collapseNow() {
// 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 300 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(true);
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 100 ms. You can change this
// value to suit your needs.
if (!currentFocus && !isPaused) {
collapseNotificationHandler.postDelayed(this, 100L);
}
}
}, 300L);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,重写onPause()和onResume方法:
@Override
protected void onPause() {
super.onPause();
// Activity's been paused
isPaused = true;
}
@Override
protected void onResume() {
super.onResume();
// Activity's been resumed
isPaused = false;
}
Run Code Online (Sandbox Code Playgroud)
完成!
注意:在将应用程序置于kiosk模式时,我使用了第一个选项,该模式根本不显示通知面板.另一方面,第二个选项运行良好,但它允许通知面板显示一小段时间,用户可以快速单击通知面板顶部的设置图标以退出自助服务终端模式.
希望这会帮助你.干杯!
| 归档时间: |
|
| 查看次数: |
9993 次 |
| 最近记录: |