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

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

  1. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Hello,

    Posting here because I have searched a long time before to find the solution. I am not an expert and without Erel's help, I wouldn't have been able to make this working.
    So, please apologize if I won't be able to help greatly.

    A sample project is attached. I have tested it from Android 2.3 to Android 5.0.2 (Nexus 7 2013).
    The project includes the code that Erel kindly translated for us in b4a.

    You will need to add those permissions into your Manifest
    Code:
    AddPermission(android.permission.SYSTEM_OVERLAY_WINDOW)
    AddPermission(android.permission.SYSTEM_ALERT_WINDOW)
    What does the code do ?
    It adds a label at the top of the StatusBar. For debugging, I did use a sentence (check the Process_Globals in the service to modify its value).

    Why do I put the code in a service ?
    Because the system kills the activity, the label stays on top for some moment and the label disappears. Using a service and restarting it when it gets killed is the way I have found to keep it running.

    Could I remove the overlay by code ?
    Yes, please see the project Overlay-OnOff attached (thanks to DonManfred)

    Can I start the service at boot time ?
    Yes, check Service Attributes


    Code:
    #Region Code to disable access to the StatusBar
    'Code translated by Erel:
    'http://www.b4x.com/android/forum/threads/overlay-over-the-status_bar.49221/#post-309833
    'Original source code:
    'http://stackoverflow.com/questions/9815901/display-view-above-status-bar/25384365#25384365
    Sub AddOverlay
    Dim mView As Label
        mView.Initialize(
    "")
        mView.Text = Sentence
        
    Dim mlp As JavaObject
        
    Dim vtype As Int = -1, pixelFormat As Int = -3
        mlp.InitializeNewInstance(
    "android.view.WindowManager$LayoutParams"Array(vtype, 1002010,296, pixelFormat))
        mlp.SetField(
    "gravity"Bit.OR(Gravity.TOP, Gravity.CENTER))
        
    Dim windowManager As JavaObject = GetContext.RunMethod("getSystemService"Array("window"))
        windowManager.RunMethod(
    "addView"Array(mView, mlp))
    End Sub

    Sub GetContext As JavaObject
        
    Return GetBA.GetField("context")
    End Sub

    Sub GetBA As JavaObject
        
    Dim jo As JavaObject
        
    Dim cls As String = Me
        cls = cls.SubString(
    "class ".Length)
        jo.InitializeStatic(cls)
        
    Return jo.GetFieldJO("processBA")
    End Sub
    #End Region
     

    Attached Files:

    Last edited: Jan 22, 2015
    jareal, carycai, MarcoRome and 10 others like this.
  2. DonManfred

    DonManfred Expert Licensed User

    i believe you need to call removeview
    [​IMG]
     
    lemonisdead likes this.
  3. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Just tried but I will have to find how to retrieve the view :)
     
  4. DonManfred

    DonManfred Expert Licensed User

    Attention. Problem here could be that you recreate the panel (view) each time you start the service... So it is always another view which you add with addView.

    Just a thought:

    Maybe you need to create a view in main activity_create (first true) and store this view in a systemglobal variable.

    In your service method AddOverlay you take the systemglobal variable (holding the view) and add this view instead of creating a new one each time

    You then can create a sub in your main similar to Addoverlay to remove the view...
     
    lemonisdead likes this.
  5. lemonisdead

    lemonisdead Well-Known Member Licensed User

    Hello, Thanks for the great idea but, I won't be able to declare a view in the Process_Globals, no ? The IDE will throw an error. Or did I misunderstood your thought ?
     
  6. DonManfred

    DonManfred Expert Licensed User

    No. you are right and i was wrong... process global can not hold views.
    Then you need to use a Global variable in your main and work with them...

    Note: Check in service whether the view is initialized!
     
    lemonisdead likes this.
  7. Informatix

    Informatix Expert Licensed User

    This solution works also under FireOS (Amazon Kindle products).
     
    DonManfred and lemonisdead like this.
  8. lemonisdead

    lemonisdead Well-Known Member Licensed User

    I have attached a sample project to Show / Hide the overlay
     
    Informatix likes this.
  9. Informatix

    Informatix Expert Licensed User

    On some tablets, the status bar is located in the bottom right corner (eg. Sony Xperia Tablet S) so the above solution does not work at all. Knowing where's located the status bar is a bit complicated and some popular solutions do not work on some devices (e.g. the popular getTop() solution does not work on a Samsung S2), so here's what I use. It seems to be reliable (tell me if it's not on your device):
    Code:
    Dim R As Reflector
    R.Target = R.GetActivity
    Dim Window As JavaObject = R.RunMethod("getWindow")
    Dim JO As JavaObject = Window.RunMethod("getDecorView"Null)
    R.Target = R.CreateObject(
    "android.graphics.Rect")
    JO.RunMethod(
    "getWindowVisibleDisplayFrame"Array As Object(R.Target))
    Dim TopLocation As Boolean = R.GetField("top") > 0
    Log("TopLocation=" & TopLocation)
    To know the height of the status bar:
    Code:
    R.Target = R.GetContext
    JO = R.RunMethod(
    "getResources")
    Dim ResourceID As Int = JO.RunMethod("getIdentifier"Array As Object("status_bar_height""dimen""android"))
    Dim Size As Int
    If ResourceID > 0 Then
         Size = JO.RunMethod(
    "getDimensionPixelSize"Array As Object(ResourceID))
    End If
    Log("Size=" & Size)
     
  10. Informatix

    Informatix Expert Licensed User

    On the Kindle tablets, my code is not reliable when FullScreen is True because of the important changes made by Amazon (the function returns TopLocation = False under FireOS so you may think that the status bar is at the bottom). So check whether the build manufacturer is Amazon before trusting the result (the status bar is always above on their devices).
     
  11. Harris

    Harris Well-Known Member Licensed User

    A small side effect....
    I have a brightness slider on my main form. When overlay is enabled, the slider will no longer adjust the brightness...
    When I remove the overly, brightness control resumes normally.

    Thanks
     
  12. Harris

    Harris Well-Known Member Licensed User

    Anyone with a suģestion on how i can work around this?
    How can i control brightness when this blocking of notify bar is in effect?

    Thanks
     
    Last edited: Oct 21, 2015
  13. Harris

    Harris Well-Known Member Licensed User

    Sorry to bump, but this is a major issue for me.
    I need to control screen brightness as well as to kiosk the device (hide notification bar).
    Now, as it stands, the users download and fire up any app they like (over an expensive sat internet). God knows what affect it has on my primary app (viruses and all).
    Thanks
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    Are you calling Phone.SetScreenBrightness? Can you upload a small project with only the overlay and the brightness functionality?
     
  15. Harris

    Harris Well-Known Member Licensed User

    DefCM.ph.SetScreenBrightness( Max(DefCM.scrndim, 5) / 100 )

    My main form has a slider for which operators can control the screen brightness.
    The line above is in every activity module to set the brightness for each form, based on initial main setting.

    I shall try and create a small demo which demonstrates the behavior. Who knows, I may uncover something in the process!

    Thanks
     
  16. Harris

    Harris Well-Known Member Licensed User

    Finally got around to creating small test app that demonstrates the issue I have with NOT being able to set screen brightness (programatically), using a seekbar when overlay is ON. Based on sample from author with brightness code added.

    This is part of my Kiosk strategy and hopefully someone way more clever than I can help resolve what the issue is here.

    Thanks
     

    Attached Files:

  17. Erel

    Erel Administrator Staff Member Licensed User

    I see it too. The activity is dimmed when the "fake" view is added to the window manager. This is a similar behavior to the dimming that happens when the notification drawer is pulled. I didn't find any way to disable this effect.
     
  18. Harris

    Harris Well-Known Member Licensed User

    CRAP!
    Now what? Perhaps we could JavaObject somehow to break around it? I dunno...
    I have always contended that Android needs 2 versions - one for general consumer and one for corporate, industrial locked down needs.

    The trouble makers at this client have already downloaded movies for Netflix (over a sat connection) and one even resorted to un-installing my app. You can see my need for a practical Kiosk mode - or I continue to fight a losing battle.

    Thanks for all suggestions and guidance.
     
    spairo likes this.
  19. Erel

    Erel Administrator Staff Member Licensed User

    I didn't find one.
     
  20. Harris

    Harris Well-Known Member Licensed User

    What do you think of this workaround:

    User touches (or swipes) in top area of screen - I lock with overlay...

    User touches anywhere below this area - I unlock overly. Now the seekbar will work and adjust screen brightness.

    Thanks
     
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