6

I have seen Kioware and SureLock applications. They simply block every control in tablet. I'm aware about overriding back button and handling the home and recent task options as well. But I'm not sure how they managed to control the setting option on system bar. Settings appear for a fraction of seconds and then disappear. In the same way Statusbar of mobile which appear on swipe down need to be block.

If anyone have idea about it please share it. Any guidance/help is appreciated.

See the attached image selected portion which I need to block/disable

Naresh Sharma
  • 4,323
  • 7
  • 48
  • 68
  • Did you get recent tasks in lollipop? Because that'll be also a problem for you, i have already gone through this type of situation. – Androider Nov 06 '15 at 18:49
  • @Androider that's not a problem. I'm looking for the setting option. That is completely disabled in surelock app. Do you have any idea about that ? – Naresh Sharma Nov 06 '15 at 18:52
  • add view over system bar – Androider Nov 06 '15 at 19:04
  • @Androider already tried that worked for status bar not in case of system bar. – Naresh Sharma Nov 09 '15 at 18:53
  • 1
    I had used http://www.sureshjoshi.com/mobile/android-kiosk-mode-without-root/ in my application. Although it works only for api level 21 or above. You can also use this code if it works @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); } } I had used this code to disable android power on/off button. – Ajay Nov 13 '15 at 11:05

3 Answers3

2

You can try to add a transparent View at desidered position using the WindowManager (follow this example). In this way, you will intercept any tap events from the user.

Be sure to set the proper flags/type, because you need to overlay the system bars:

    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);
Community
  • 1
  • 1
bonnyz
  • 13,458
  • 5
  • 46
  • 70
2

The trick is to add transparent custom view that overlays on the system bar, that way all user interaction like touch, drag will be consumed by the custom view.

Here is a working code:

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);

Custom 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;
        }
    }

I myself have done locking feature to my app though I have separated the locking feature into a different app for many reasons. You can ask for more information and I will put them here if necessary.

dsharew
  • 10,377
  • 6
  • 49
  • 75
-1

Finally I found the solution of the above problem. onWindowFocus change I just closed the system generated Dialogs and my problem was solved. below is the sample code.

@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); 

      }

     }

Update:

In Mobile to block the status bar which appear on swipe down on the screen use below way.

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" boolean which set true when app is in Pause state.

Naresh Sharma
  • 4,323
  • 7
  • 48
  • 68