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

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
B4X:
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


B4X:
#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, 100, 2010,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
 

Attachments

Last edited:

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

Well-Known Member
Licensed User
store this view in a systemglobal variable
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 ?
 

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):
B4X:
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:
B4X:
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)
 

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

Harris

Expert
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
 

Harris

Expert
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:

Harris

Expert
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
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
 

Harris

Expert
Licensed User
Are you calling Phone.SetScreenBrightness? Can you upload a small project with only the overlay and the brightness functionality?
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
 

Harris

Expert
Licensed User
Are you calling Phone.SetScreenBrightness? Can you upload a small project with only the overlay and the brightness functionality?
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
 

Attachments

Harris

Expert
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.
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.
 

Harris

Expert
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
 
Top