android 禁用通知面板下拉

yqkkidmi  于 2023-06-20  发布在  Android
关注(0)|答案(6)|浏览(537)

我正在开发一个锁屏应用程序,我需要禁用在屏幕顶部拉下通知/状态栏的功能。有一个叫做Holo Locker的应用程序,这个应用程序的作用是当用户从屏幕顶部向下拉时,它只是将酒吧设置回屏幕顶部,使其无法向下拉抽屉。
我不知道从何说起。任何帮助将是伟大的!谢谢!

xhv8bpkk

xhv8bpkk1#

这可以使用反射。但也有很多问题。
没有办法检查通知面板是否打开或正在打开。因此,我们必须依赖Activity#onWindowFocusChanged(boolean)。这就是问题的开始。
该方法的作用:
public void onWindowFocusChanged(boolean hasFocus)
当Activity的当前Window获得或失去焦点时调用。这是此活动是否对用户可见的最佳指示器。
因此,我们必须找出一种方法来区分由于显示通知面板而导致的焦点丢失和由于其他事件而导致的焦点丢失。
一些会触发onWindowFocusChanged(boolean)的事件:

  • 当Activity被发送到后台(用户切换应用程序或按下home按钮)时,窗口焦点丢失
  • 由于Dialogs和PopupWindows在各自独立的窗口中打开,因此当显示它们时,Activity的窗口焦点将丢失。
  • Activity窗口失去焦点的另一个示例是,单击微调器时,显示PopupWindow。

您的活动可能不必处理所有这些问题。下面的示例处理其中的一个子集:
首先,您需要EXPAND_STATUS_BAR权限:

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

接下来,在Activity中声明这些类作用域变量:

  1. // To keep track of activity's window focus
  2. boolean currentFocus;
  3. // To keep track of activity's foreground/background status
  4. boolean isPaused;
  5. Handler collapseNotificationHandler;

覆盖onWindowFocusChanged(boolean)

  1. @Override
  2. public void onWindowFocusChanged(boolean hasFocus) {
  3. currentFocus = hasFocus;
  4. if (!hasFocus) {
  5. // Method that handles loss of window focus
  6. collapseNow();
  7. }
  8. }

定义collapseNow()

  1. public void collapseNow() {
  2. // Initialize 'collapseNotificationHandler'
  3. if (collapseNotificationHandler == null) {
  4. collapseNotificationHandler = new Handler();
  5. }
  6. // If window focus has been lost && activity is not in a paused state
  7. // Its a valid check because showing of notification panel
  8. // steals the focus from current activity's window, but does not
  9. // 'pause' the activity
  10. if (!currentFocus && !isPaused) {
  11. // Post a Runnable with some delay - currently set to 300 ms
  12. collapseNotificationHandler.postDelayed(new Runnable() {
  13. @Override
  14. public void run() {
  15. // Use reflection to trigger a method from 'StatusBarManager'
  16. Object statusBarService = getSystemService("statusbar");
  17. Class<?> statusBarManager = null;
  18. try {
  19. statusBarManager = Class.forName("android.app.StatusBarManager");
  20. } catch (ClassNotFoundException e) {
  21. e.printStackTrace();
  22. }
  23. Method collapseStatusBar = null;
  24. try {
  25. // Prior to API 17, the method to call is 'collapse()'
  26. // API 17 onwards, the method to call is `collapsePanels()`
  27. if (Build.VERSION.SDK_INT > 16) {
  28. collapseStatusBar = statusBarManager .getMethod("collapsePanels");
  29. } else {
  30. collapseStatusBar = statusBarManager .getMethod("collapse");
  31. }
  32. } catch (NoSuchMethodException e) {
  33. e.printStackTrace();
  34. }
  35. collapseStatusBar.setAccessible(true);
  36. try {
  37. collapseStatusBar.invoke(statusBarService);
  38. } catch (IllegalArgumentException e) {
  39. e.printStackTrace();
  40. } catch (IllegalAccessException e) {
  41. e.printStackTrace();
  42. } catch (InvocationTargetException e) {
  43. e.printStackTrace();
  44. }
  45. // Check if the window focus has been returned
  46. // If it hasn't been returned, post this Runnable again
  47. // Currently, the delay is 100 ms. You can change this
  48. // value to suit your needs.
  49. if (!currentFocus && !isPaused) {
  50. collapseNotificationHandler.postDelayed(this, 100L);
  51. }
  52. }
  53. }, 300L);
  54. }
  55. }

处理Activity的onPause()onResume()

  1. @Override
  2. protected void onPause() {
  3. super.onPause();
  4. // Activity's been paused
  5. isPaused = true;
  6. }
  7. @Override
  8. protected void onResume() {
  9. super.onResume();
  10. // Activity's been resumed
  11. isPaused = false;
  12. }

希望这是接近你正在寻找的。
注意:当您滑动通知栏并按住它时发生的 Flink 是不可避免的。然而,其外观可以使用处理器延迟的“更好”值来控制/改进。这个问题也存在于Holo Locker应用程序中。

展开查看全部
mepcadol

mepcadol2#

如果您只是想阻止用户打开状态,请尝试以下操作:

  1. getWindow().addFlags(WindowManager.LayoutParams.[TYPE_SYSTEM_OVERLAY][1]);

用途:

  1. super.onCreate(savedInstanceState);
  2. getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
  3. setContentView(R.layout.your_layout);

根据您的具体需要,您可以选择适当的WindowManager.LayoutParams
希望这能帮上忙。

cunj1qz1

cunj1qz13#

  1. private void disablePullNotificationTouch() {
  2. WindowManager manager = ((WindowManager) getApplicationContext()
  3. .getSystemService(Context.WINDOW_SERVICE));
  4. WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
  5. localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
  6. localLayoutParams.gravity = Gravity.TOP;
  7. localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
  8. // this is to enable the notification to recieve touch events
  9. WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
  10. // Draws over status bar
  11. WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
  12. localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
  13. localLayoutParams.height = (int) (25 * getResources()
  14. .getDisplayMetrics().scaledDensity);
  15. localLayoutParams.format = PixelFormat.RGBX_8888;
  16. customViewGroup view = new customViewGroup(this);
  17. manager.addView(view, localLayoutParams);
  18. }
  19. //Add this class in your project
  20. public class customViewGroup extends ViewGroup {
  21. public customViewGroup(Context context) {
  22. super(context);
  23. }
  24. @Override
  25. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  26. }
  27. @Override
  28. public boolean onInterceptTouchEvent(MotionEvent ev) {
  29. Log.v("customViewGroup", "**********Intercepted");
  30. return true;
  31. }
展开查看全部
jgzswidk

jgzswidk4#

我尝试了接受的答案,但我仍然能够拉下来,并迅速改变一些设置。
有一个不同的解决方案,防止用户完全拉下菜单,我更喜欢这里接受的答案。

mwecs4sa

mwecs4sa5#

  1. WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
  2. WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
  3. localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
  4. localLayoutParams.gravity = Gravity.TOP;
  5. localLayoutParams.flags =
  6. WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
  7. // this is to enable the notification to receive touch events
  8. WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
  9. // Draws over status bar
  10. WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
  11. localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
  12. localLayoutParams.height = (int) (40 * getResources().getDisplayMetrics().scaledDensity);
  13. localLayoutParams.format = PixelFormat.TRANSPARENT;
  14. blockingView = new CustomViewGroup(this);
  15. manager.addView(blockingView, localLayoutParams);

使用此命令并引用link以获得类customViewGroup

展开查看全部
xmakbtuz

xmakbtuz6#

听起来是个好主意。你会破坏用户期望的默认操作系统功能。幸运的是,我不认为这是可能的,但你实现了类似的东西,使您的活动全屏。

  1. public class FullScreen extends Activity {
  2. @Override
  3. public void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. requestWindowFeature(Window.FEATURE_NO_TITLE);
  6. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  7. WindowManager.LayoutParams.FLAG_FULLSCREEN);
  8. setContentView(R.layout.main);
  9. }
  10. }

如果你找到比这更好的解决办法,一定要让我知道,我会渴望知道的。
谢谢你。

展开查看全部

相关问题