Android Code Snippet Disable access to the StatusBar (Notification bar)

Discussion in 'Code Snippets' started by lemonisdead, Jan 22, 2015.

  1. Erel

    Erel Administrator Staff Member Licensed User

    Might work. Worth a test.
     
  2. Harris

    Harris Well-Known Member Licensed User

    Yes it does work!
    I used the timer (and a boolean) I already have going to control it.

    Touch the top of screen ( 0 to 30 dip) and overlay is enabled. I set the color of panel to black so you don't even see the status bar.
    Five seconds later, the timer releases it. Works for me!

    Now, for the other half of kiosk mode... I am thinking of setting my app as home screen, as described in methods to kiosk effectively.

    Thanks for the inspiration...
     
  3. Informatix

    Informatix Expert Licensed User

    I noticed that this issue happens only when you allow the overlay window to move over the status and notification areas (window with type SYSTEM_ERROR and flag LAYOUT_IN_SCREEN). If you restrict it to the application area, you can change the screen brightness.
    The simplest solution is to use the OverlayWindow lib available in my ProBundle.
     
  4. Harris

    Harris Well-Known Member Licensed User


    @Informatix, Sounds great. Have you tested it, with your lib, with the sample test project I submitted?
    If so and it works, I shall surely get your ProBundle. That would be better than my timer solution.

    Thanks Kindly.
     
  5. Informatix

    Informatix Expert Licensed User

    Yes I tried. If I create the window with my lib via Initialize2 (which allows to go over the notification and status bars), I cannot change the brightness. If I create the window via Initialize, I can change the brightness without issue.
    • Initialize (X As Int, Y As Int, Width As Int, Height As Int, EventPrefix As String)
      Creates an empty overlay window at the specified position. The window is displayed after calling Open.
      The window has a panel which can contain child views. Note that these views cannot acquire the focus.
      The window cannot be placed or moved over the status and notification bars.
      Width: Width of the window.
      Height: Height of the window.
      EventPrefix: Prefix of the Touch, Click and LongClick events.
    • Initialize2 (X As Int, Y As Int, Width As Int, Height As Int, EventPrefix As String)
      Creates an empty overlay window at the specified position. The window is displayed after calling Open.
      The window has a panel which can contain child views. Note that these views cannot acquire the focus.
      The window can be placed or moved over the status and notification bars.
      Width: Width of the window.
      Height: Height of the window.
      EventPrefix: Prefix of the Touch, Click and LongClick events.
     
  6. Harris

    Harris Well-Known Member Licensed User

    The window cannot be placed or moved over the status and notification bars.
    With Initialize- is this true? (or can it be ignored) The purpose is to block access to status/notify while maintaining the ability to set brightness...
     
  7. Informatix

    Informatix Expert Licensed User

    Strange question. Why would I add such a comment if it was false? "Cannot" means that's impossible.
    I never implemented this feature (blocking the status/notification bars with an overlay window) in my app MyPlayground because I saw 3 particular cases on my own devices and one of them was so complicated to handle that I prefered to give up. Moreover I have no idea of the total number of particular cases to handle.

    To solve your issue, maybe you can close the window while you set the brightness and restore the window after that but I doubt that works fine. As explained in #25, only the window created with Initialize can allow you to alter the brightness, but it cannot act as a blocker for the bars, and you cannot switch from a window type to another.

    You're not the only one expecting a solution:
    http://stackoverflow.com/questions/...n-screen-brightness-and-in-hidding-status-bar
    It's probably impossible.
     
    Last edited: Jul 18, 2016
  8. Harris

    Harris Well-Known Member Licensed User

    Hummm, that is where I got confused. I thought initially you stated that (post 23) Overlay would resolve the issue until you posted the init methods in #25.
    Yes, it is a sticky wicket - difficult to implement with desired results. My timer solution does work (for now) - just not as elegant as a straight forward approach - which doesn't seem possible.
    Thanks for you help.
     
  9. Informatix

    Informatix Expert Licensed User

    The posts #23 and #25 say basically the same thing, though. My last sentence in post #23 just says that's simpler to create an overlay window and test both cases with my lib. Nothing else. But I see now that the word "solution" probably confused you.
    There's no ambiguity in post #25 about the fact that my lib does not solve the problem. It's a confirmation of post #23.
    I don't understand the solution with the timer. Could you post your code?
    I tried the solution that I suggested in #27 (closing the window, changing the brightness, reopening the window) and, as I expected, that only works temporarily. As soon as you reopen the window, the brightness is restored.
     
  10. Harris

    Harris Well-Known Member Licensed User

    Here is the short version...

    Touch the top of screen (y <= 30) and overlay will lock it... (the top 30 - painted black)
    The timer checks to see (among many other things) if it is locked and unlocks it after 6 seconds - hence restoring the users ability to adjust screen brightness...

    In the AddOverlay and RemoveOverlay, I set "islock" flag accordingly.

    Yes, an absolute downright workaround ( ok - hack ), but it works for me (for now).

    Code:
    Sub Activity_Touch( Action As Int, X As Float, Y As Float)
       
    If y <= 30 Then
           
    If JobServMod.islock = False Then
              CallSubDelayed(JobServMod,
    "AddOverlay")
           
    End If
       
    End If     
    End Sub


    ' In timer_tick... (ticks every 2 seconds)

        
    If JobServMod.islock Then
           ovlval = ovlval + 
    1
           
    If ovlval > 3 Then
                ovlval = 
    0
                CallSubDelayed(JobServMod ,
    "RemoveOverlay")
           
    End If
       
    End If
     
    Informatix likes this.
  11. Informatix

    Informatix Expert Licensed User

    Your code presumes that all bars are above, which is wrong on many tablets, and requires that the activity is in full screen with no title. In this code, I don't understand the usefulness of ovlval. Why don't you set directly the interval to 8 sec. (4 x 2 sec.)?

    I made an attempt with the code above and the timer takes a long time to remove the overlay window and restore the brightness at its chosen level, so the visual effect is confusing (you may think that you lost the brightness value and try to reset it). But, if you shorten that time, it becomes easy to open the notification area with a succession of quick gestures. In the end, that's not very satisfying IMHO.
     

    Attached Files:

  12. Harris

    Harris Well-Known Member Licensed User

    This is a custom project for one specific client (Teck Resources (NANA/Lynden Transport) / Red Dog Mine, Alaska, USA). They use the Samsung Active 8 tablet (commercial/industrial) with a powered cradle in semi-trucks - locked in landscape mode.
    And yes, the screen brightness will resort to whatever the OS setting was - and resume to whatever the user set it to... So be it.
    Try hard and long enough and you will unlock the notifications... ( I doubt they will... ) If I could, I would record this event as a violation of company policies - hey fellas - don't Fu#$ with the system!

    Like I said, good enough for me for now since I have so many other pressing issues to deal with - this is just one ounce of prevention.
    Thanks for your input, it is always insightful.


    active8.png

    20160421_151145.jpg
     
  13. Informatix

    Informatix Expert Licensed User

    I looked at the code of SetScreenBrightness and saw that it does not change the brightness of the screen, but only the brightness of the activity. That's why the brightness changes when the overlay window is displayed outside the application area.
    I created a small library that allows to really change the brightness of the screen. Now, with it, you should not encounter any issue.
     

    Attached Files:

    Ohanian likes this.
  14. Harris

    Harris Well-Known Member Licensed User

    Hey! Looking Good!

    I tried it with my stub app (attached).

    Setting the screen brightness (Master setting) as opposed to current activity is most appealing.
    This way, all views are at the same brightness - don't have to set it each time a new activity is presented (as I must do now).

    However, as the stub app shows (and picture attached), setting slider value to 100 percent will only set screen brightness to (about) 40 percent (whether or not overlay is locked). Naturally, I must be doing something wrong.

    If you can find the time, pls mock this test to show all the features and method uses of the brightness lib.

    Thanks again.
     

    Attached Files:

  15. Informatix

    Informatix Expert Licensed User

    The max value for the screen brightness is 255, not 100.
     
    Erel likes this.
  16. Harris

    Harris Well-Known Member Licensed User

    Yes, there ya go... I knew I was missing something! Just got to read the fine print...

    Works great. This is, with or without an overlay, EXACTLY what I needed.
    No more need to timer control the overlay and set the screen brightness once - for the entire app!

    We are so very fortunate to have pure genius in our camp at B4X.

    Thanks again and look for a donation next week...
     
    DonManfred, Erel and Informatix like this.
  17. fransvlaarhoven

    fransvlaarhoven Active Member Licensed User

    Hello,

    I've a problem with the code to add an overlay:

    - with android 5.1 all runs fine

    - with android 6, the code generates an error en no overlay is added:

    java.lang.SecurityException: com.messenger from uid 10000 not allowed to perform SYSTEM_ALERT_WINDOW

    those lines are in the manifest:
    AddPermission(android.permission.SYSTEM_OVERLAY_WINDOW)
    AddPermission(android.permission.SYSTEM_ALERT_WINDOW)

    Is something like this possible with android 6?
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    I've tested the example project on Android 7 and it works without any errors.
     
  19. fransvlaarhoven

    fransvlaarhoven Active Member Licensed User

    Hello Erel,

    I've also done some testing myself:

    The problem seems to be the line in the manifest:

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="23"/>

    Once you set android:targetSdkVersion to 23 or higher, you need additional permission for adding overlays.
    for android:targetSdkVersion= 22 or lower, this permission is granted automatically.

    I need to do some further testing but I solved the problem by reinstalling the app with android:targetSdkVersion="22"
     
    Erel and Informatix like this.
  20. wes58

    wes58 Active Member Licensed User

    As far as targetSdkVersion higher than 22, on Samsung phones you can do it this way:
    1. Go to SETTINGS
    2. Go to APPS
    3. On the menu click on APPS THAT CAN APPEAR ON TOP
    4. Select your application and enable this option.
    Now the overlay should work.

    Now, going back to my problem. I want to have an overlay to cover the whole screen - and disable all controls behind it.
    In the example that you posted, I added a panel to the layout that covers the whole screen. I make it visible when the overlay is shown. When I click anywhere on the screen, none of the controls behind the panel are responding to touch/click events.
    I did the same in my application but the controls are responding to touch event.
    Any idea why?

    Is there a way for the overlay to cover the whole screen?

    SOLVED:
    It seems that setting the width and height of the label in the AddOverlay sub fixes the problem:
    mlp.InitializeNewInstance("android.view.WindowManager$LayoutParams", Array(vtype, 100, 2010,296, pixelFormat))
    mlp.SetField("gravity", Bit.Or(Gravity.TOP, Gravity.CENTER))
    mlp.SetField("height", 2000)
    mlp.SetField("width", 1000)
    Dim windowManager As JavaObject = GetContext.RunMethod("getSystemService", Array("window"))
    windowManager.RunMethod("addView", Array(mView, mlp))

    Since this sub in the Service, how do I get the size of the screen. I can't use 100%x, 100%y?
     
    Last edited: Jul 31, 2017
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice