Some background information:
My app will be used by guests at an event to perform self check-ins. They should not be able to navigate away from the page, access the device's settings, etc. This means that it has to enter a Kiosk Mode of sorts.
I need to disable the notifications tray completely, meaning even if the user swipes downward from the top of the screen, the status bar should not appear. It's the one which shows your battery life, WiFi/3G connection, etc.
I have already made my application fullscreen, which hides the status bar, but somehow the status bar still appears once the user swipes downward from the top of the screen. Performing another swipe will subsequently open the notifications tray.
My device runs on Jelly Bean, but is aimed to cater to devices as old as Ice Cream Sandwich.
How should I go about disabling the notifications tray? Is there code that can help me, or is it as simple as advising the user to disable some settings of some sort (like how the iPad can simply disable gestures in the device's settings)?
Thanks in advance,
Rei
Take a look at this.
View disableStatusBar = new View(context);
WindowManager.LayoutParams handleParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
<height of the status bar>,
// This allows the view to be displayed over the status bar
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
// this is to keep button presses going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
handleParams.gravity = Gravity.TOP;
context.getWindow().addView(view, handleParams);
Related
I have created an overlay activity the requests permission to create a window of type TYPE_APPLICATION_OVERLAY and then starts a service that creates the window. This all works fine and I can interact with it and the launcher home screen behind the view (It's just a search text box with interactive results as you type).
The problem is, I have found one application that when I have this overlay running, the application is frozen like it's paused (it's a game). But I have tried my overlay over other applications and it works fine like google maps and even another game.
Here is how I'm creating the window in the service
//Add the view to the window.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
//Specify the view position
params.gravity = Gravity.TOP | Gravity.LEFT; //Initially view will be added to top-left corner
params.x = 0;
//Add the view to the window
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mFloatingView, params);
I've also tried other apps like facebook chat heads on top of this problem application and the app works with them so it has to be doable.
Has anyone run into this before? I'm really new to Android programming so I'm just not sure what to look for
Thanks!
EDITI found that if I use FLAG_NOT_FOCUSABLE then the problem app works underneath it. But then I can't interact with the overlay :/
That application might have some code written in its onPause() method to freeze it. Usually games pause themselves in onStop() or in onPause(), so that user doesn't accidentally lose their progress. Like if a phone call comes, or they press the home or recents button.
I figured it out based on this class of the Floaties library.
https://github.com/ericbhatti/floaties/blob/master/FloatiesLibrary/floaties/src/main/java/com/bezyapps/floatieslibrary/Floaty.java
The window manager can update view params via the updateViewLayout method. Just have to remove the FLAG_NOT_FOCUSABLE and re-add it in the two different states of my overlay when I want to be able to input text or not
I am creating a lock screen application right now. I have been searching and trying some tricks to do it but still can't find the best approach. My previous approach that I used is to use TYPE_SYSTEM_ERROR. it worked well. it prevents navigation and status bar to get any touches. it also run any other app behind my app, including the power off options dialog.
unfortunately I think this is bad because when the app got freeze or not responding, user can't do anything but force restart his/her phone.
I have been looking and analyze some existing lock screen apps in play store. They use different ways to lock the phone but I found one app that I think I can follow. It makes the nav and status bar overlay the app. nav and status bar still can be clicked but it's all opened behind the lock screen. and when I tried to open the power off dialogs, the NavigationBar still overlay the lock screen.
I changed my app to follow that approach. I am able to make the bars overlay my lock screen but I am still not able to:
1. make other app run behind my lock screen (lock screen always on top)
2. the NavigationBar stays overlay when power off dialog appear and when user move to home as well. in my case, the NavigationBar pushed up the screen and my screen looks ugly (some components move to wrong place) and after the Dialog dismissed, it doesn't move back to original position. it's fixed but I noticed a similar problem when I touch the home button and still searching to fix this.
Here's a snippet of my codes (updated):
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
} else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
mOverlay = (RelativeLayout) inflater
.inflate(R.layout.main, (ViewGroup) null);
mOverlay.setFitsSystemWindows(false);
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
mWindowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(mOverlay, params);
And here a screenshot of app in PlayStore that I want to follow:
Im developing an android application for a school and i want this application when opened to prevent the user from doing anything on the device except what im offering inside my application, and i mean doing NOTHING else...
so first the Navigation bar should be disabled and hided
i saw this but its for 4.4+ and it doesn't solve the problem because if you swipe the screen you will get the menu back.
(How to hide navigation bar permanently in android activity?)
this doesn't work also(Permanently hide navigation bar on activity) (Is there a way to hide the system/navigation bar in Android ICS)
i also tried to disable navigation bar actions using onKeyDown but it didn't work on all of the keys.
in addition i want to remove the notification bar which make the user access the settings of the device and other things..
and this not working also (Disable the notification panel from being pulled down) as mentioned in this link it doesn't solve it, it just hides it after showing it :S
help would be appreciated,
Thanks.
You can get a kiosk type mode in Android 5.0, using the screen pinning feature mentioned here:
Android 5.0 introduces a new screen pinning API that lets you
temporarily restrict users from leaving your task or being interrupted
by notifications. This could be used, for example, if you are
developing an education app to support high stakes assessment
requirements on Android, or a single-purpose or kiosk application.
Once your app activates screen pinning, users cannot see
notifications, access other apps, or return to the home screen, until
your app exits the mode.
You can lock the device down to be a kiosk. The navigation bar is not hidden, but the home and recents buttons can be removed or disabled depending how you activate the mode. I wrote some information after testing this feature here.
Its possible
To disable the Status NotificationBar:
You need to place a view on top of the notification bar, so that we hijack the touch events to the Status notification bar. Without further ado, here is the code:
mView= new TextView(this);
mView.setText(".........................................................................");
mLP = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
100,
// Allows the view to be on top of the StatusBar
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
// Keeps the button presses from going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// Enables the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
mLP.gravity = Gravity.TOP|Gravity.CENTER;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mView, mLP);
And since you are using the system overlay window, you need the permission:
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
Note:
Do not make your app full screen, as the versions above 17, which supports immersive mode, will screw this approach.
You can NOT disable the system or notification panel in Android.
You can hide these elements (like you have already discovered), but currently, you can NOT disable them permanently.
You are looking for a 'Kiosk Mode' which is not supported.
The closest thing to what you are looking for is 'Immersive Mode' (details) - but this does NOT hide the settings or navigation controls permanently.
I'm trying to create an app like the Halo Notification on Paranoid Android. So far, so good.
However, when my "halo" is on the screen I can move it around just fine and most of the touch events do work. However, when I try popping the keyboard up by tapping on an EditText nothing happens. The window seems to consume the focus. The back button also doesn't work, but the home and recent apps buttons work.
I'm testing the application on a rooted Nexus 4 running PA's AOSP 4.4
The code (layout parameters) I have used to create the halo window is:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
Any idea what's causing this selective consumption of touch events?
Try to add the flag: FLAG_NOT_FOCUSABLE .
In my video play app, I use this flag: SYSTEM_UI_FLAG_HIDE_NAVIGATION to make the navigation bar disappear, but when I touch the screen, the navigation bar appears, after the first touch, my touch events and other events work fine.
My question is how can I take over the first touch?
You can't really take over the first event. You could implement View.OnSystemUiVisibilityChangeListener and be notified when the navigation bar is shown or hidden again, and then depending on its current state do what you wanted on the first touch, if possible.
However, there is no way you can completely take over the first touch, as stated in the documentation for SYSTEM_UI_FLAG_HIDE_NAVIGATION:
There is a limitation: because navigation controls are so important, the least user interaction will cause them to reappear immediately. When this happens, both this flag and SYSTEM_UI_FLAG_FULLSCREEN will be cleared automatically, so that both elements reappear at the same time.
For anyone coming across this post, if your intention is to hide the navigation/status bar and not have it come back up when you touch the screen, take a look at the different "immersive" configurations as described here: https://developer.android.com/training/system-ui/immersive
for example:
currentActivity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
That would effectively put your screen in "Full Screen" Mode regardless of any interaction the user has with the screen
To show the navigation/status bar again, simply change it back to:
currentActivity?.window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE