被推倒禁用通知面板面板、通知

2023-09-12 08:00:35 作者:挽辞

我工作的一个锁屏应用程序,我需要禁用拉下通知/状态栏在屏幕上方的能力。有一个叫洛克霍洛一个应用程序,什么这个程序的作用是,当用户从屏幕顶部往下拉,它只是设置了酒吧备份到屏幕的顶部,使其无法拉开抽屉下来。

I am working on a lockscreen app and I need to disable the ability to pull down the notification/status bar at the top of the screen. There is an app called Holo Locker and what this app does is when the user pulls down from the top of the screen, it just sets the bar back up to the top of the screen and making it impossible to pull the drawer down.

我不知道从哪里开始。任何帮助将是巨大的! 谢谢!

I have no idea where to start. Any help would be great! Thanks!

推荐答案

这是有可能使用反射。有很多的问题,但。

This is possible using reflection. There are plenty of problems though.

有没有办法来检查的通知面板打开,或打开。因此,我们必须依靠活动#onWindowFocusChanged(布尔)。而这就是问题的开始。

There's no way to check if the notification panel is open, or opening. So, we'll have to rely on Activity#onWindowFocusChanged(boolean). And this is where the problems begin.

什么方法做:

公共无效onWindowFocusChanged(布尔hasFocus)

public void onWindowFocusChanged (boolean hasFocus)

调用时的活动收益的当前窗口或失去焦点。   这是此是否活动的最佳指标是可见的   用户。

Called when the current Window of the activity gains or loses focus. This is the best indicator of whether this activity is visible to the user.

所以,我们必须想出一个办法焦点损失区别开来,由于显示通知面板,并专注损失,因为其他事件。

So, we'll have to figure out a way to distinguish between focus-loss due to showing of notification panel, and focus-loss because of other events.

这将触发 onWindowFocusChanged(布尔)有些事件:

在活动发送到后台窗口焦点丢失(用户切换应用程序,或pressing的家居按钮)

由于对话框和PopupWindows在自己单独的窗口中打开,这些都显示在活动的窗口焦点将丢失。

Since Dialogs and PopupWindows open in their own separate windows, the activity's window focus will be lost when these are displayed.

另外一个实例,该活动的窗口会失去焦点是,当一个微调被点击后,显示PopupWindow。

Another instance in which the activity's window will lose focus is when a spinner is clicked upon, displaying a PopupWindow.

您的活动可能没有处理所有这些问题。下面的例子中处理它们的一个子集

Your activity may not have to deal with all of these issues. The following example handles a subset of them:

首先,你需要在 EXPAND_STATUS_BAR 的权限:

Firstly, you need the EXPAND_STATUS_BAR permission:

<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />

接下来,在你的活动中声明这些类范围的变量:

Next, declare these class-scope variable in your activity:

// To keep track of activity's window focus
boolean currentFocus;

// To keep track of activity's foreground/background status
boolean isPaused;

Handler collapseNotificationHandler;

覆盖 onWindowFocusChanged(布尔)

@Override
public void onWindowFocusChanged(boolean hasFocus) {

    currentFocus = hasFocus;

    if (!hasFocus) {

        // Method that handles loss of window focus
        collapseNow();
    }
}

定义 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);
    }   
}

拉​​手活动的的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;
}

希望这是接近你所期待的。

Hope this is close to what you are looking for.

注:当你滑动通知栏,并坚持到这家饭店目前无法避免这种情况发生的闪烁。用'好'的值处理程序,延迟它的出现可以但控制/改善。这问题也present在全息储物柜应用程序。

Note: The flicker that happens when you slide the notification bar and hold on to it is unfortunately unavoidable. Its appearance can however be controlled/improved using 'better' values for handler-delays. This is issue is also present in the Holo Locker app.