Close status bar when opened: Android - android

I am trying to come up with some ways of disabling the status bar without hiding it completely. This is an introlude attempt at disabling status bars in 3rd party apps. For now, I want to disable it in my own app, and then eventually create a background service to see if I can do so in other apps. The app I am creating is an operating system for children, and I am trying to develop a closed system.
Here is what I have tried. My initial idea was to monitor when status bar was accessed and then closing it.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.i(TAG, "onWindowFocusChanged()");
try {
if (!hasFocus) {
Log.d(TAG, "close status bar attempt");
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class
.forName("android.app.StatusBarManager");
Method collapse = statusbarManager.getMethod("collapse");
collapse.setAccessible(true);
collapse.invoke(service);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
This is the method I used. It works for detecting when status bar is being accessed, however, it does not close the status bar once it has focus. What am I missing? Thanks in advance.

I have found answer to my question. First, I was missing the following permission
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
With that permission, the following code now works really well.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.i(TAG, "onWindowFocusChanged()");
try {
if (!hasFocus) {
Log.d(TAG, "close status bar attempt");
//option 1
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class
.forName("android.app.StatusBarManager");
if (currentApiVersion <= 16) {
Method collapse = statusbarManager.getMethod("collapse");
collapse.setAccessible(true);
collapse.invoke(service);
} else {
Method collapse = statusbarManager.getMethod("collapsePanels");
collapse.setAccessible(true);
collapse.invoke(service);
}
// option 2
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(it);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
If you notice, there is a second option as well that I found to be working good. You can comment out option 1 if you want to use option 2, or vise versa. Both accomplish the same thing, although I believe option 2 is better.
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(it);
The only downfall I found is that it is slow(er) when closing. However, both methods collapse quick enough to where no one can click on any notifications or options in the status bar. Hopefully this is helpful to someone else. Good luck, Cheers!

I am also working on the same thing. With Android 5.0 Lolipop they have released Screen Pinning mode (which is essentially Kiosk mode) which does a few things:
The status bar is blank, and user notifications and status information are hidden.
The Home and Recent Apps buttons are hidden.
Other apps cannot launch new activities.
The current app can start new activities, as long as doing so does not create new tasks.
When screen pinning is invoked by a device owner, the user remains locked to your app until the app calls stopLockTask().
If screen pinning is activity by another app that is not a device owner or by the user directly, the user can exit by holding both the Back and Recent buttons.
You can read about it further in the Android 5.0 Lolipop release documentation.
However, if you are looking for a more controlable solution, then you may want to create a custom ROM. Here is a great overview on making Kiosk applications (which also require disabling status bar).
Developing Kiosk Mode Applications in Android Tutorial

Here's an updated answer if anyone is still looking for a solution to something like this: https://developer.android.com/training/system-ui/immersive.html
For me, I added the following in my onResume() method:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
This allows the status bar to stay hidden but the user can still access it by swiping the edge of the screen. Then after a few seconds of inactivity it will collapse and disappear again!

Related

Disable status bar on rooted device(system signed application) in device locked mode

I am working on a kiosk application which would work in single app mode on device and the activity would be on top everytime. I even want the user to restrict use of notification panel when the activity is on top. For this I am using below system API :
try {
android.app.StatusBarManager service = (StatusBarManager) context.getSystemService("statusbar");
service.disable(DISABLE_EXPAND);
} catch (Exception e) {
e.printStrackTrace();
}
This works correctly when user try to scroll down the notification panel, but if screen lock is configured and user tries to scroll down the panel, it doesn't gets disabled and expands.
Can someone help me understand what could be the possible issue.

Android dismiss a system dialog programmatically

I want to dismiss a system generated alert dialog programmatically. I have tried all solutions provided here(stackoverflow) but it does not seem to work.
This is the accepted answer mostly everywhere, but it only dismisses notification panel and recent tasks menu.
I have tested it on devices with os version 4.0.3, 4.2.2, 4.4.2 and 5.1.1, it has the same behavior on all of them. There are apps which can actually dismiss all system dialogs (Mubble). Can someone suggest how it is done?
Thanks
The usual answer to this is
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
However, this does not work for everything. In particular, on some devices it does not work for the "recent apps" list.
The solution is to detect when your app loses focus and then move your app to the front. Note that your app will need the permission android.permission.REORDER_TASKS to do this.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
this.keepFocus = true;
}
if (! hasFocus && this.keepFocus) {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME );
}
}

android intercept recent apps button

I have an application meant for children and I do not want them to be able to click the "Recent Apps" button (the one that looks like two rectangles on top of each other). I am taking care of capturing the back button and the home button and I have searched and read a lot about about trying to capture the Recent Apps button, but most say you cannot or the way they do it is very questionable.
The App "Kids Place" pops up a view that says "Action Not Allowed" and redirects you to its home screen if you press the Recent Apps button, this works even if you are in a different app, so how are they doing this?
Any suggestions, hints would be appreciated.
Thanks.
After lots of searching and coding the current best solution I found is the following:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
windowCloseHandler.postDelayed(windowCloserRunnable, 0);
}
}
private void toggleRecents() {
Intent closeRecents = new Intent("com.android.systemui.recent.action.TOGGLE_RECENTS");
closeRecents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
ComponentName recents = new ComponentName("com.android.systemui", "com.android.systemui.recent.RecentsActivity");
closeRecents.setComponent(recents);
this.startActivity(closeRecents);
}
private Handler windowCloseHandler = new Handler();
private Runnable windowCloserRunnable = new Runnable() {
#Override
public void run() {
ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
if (cn != null && cn.getClassName().equals("com.android.systemui.recent.RecentsActivity")) {
toggleRecents();
}
}
}
This requires that you use <uses-permission android:name="android.permission.GET_TASKS" />
When using this approach when the user presses the recent apps button it will cause your activity will go through the activity lifecycle as follows: onPause -> onWindowFocusChanged -> onResume.
To the user the behavior appears that pressing the recent apps button has no response. NOTE: that I have found that if you press the recent apps button quickly it will display that view for brief time.
This is not the best solution, but it is a stab at it. If you have a better solution please share.
The best way I have found is to do this:
public class BaseActivity extends Activity {
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.d("Focus debug", "Focus changed !");
if(!hasFocus) {
Log.d("Focus debug", "Lost focus !");
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(closeDialog);
}
}
}// all credit goes here: http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/
This is not my own code, but this just hides the recent apps list from showing.
In the accepted answer you're using ClassName only for Android 4.2 - 4.4. It won't work on 5.0 and higher, or Android 4.1.
Here is the list of ClassNames for main Android versions:
Android 4.1: "com.android.internal.policy.impl.RecentApplicationsDialog"
Android 4.2 - 4.4: "com.android.systemui.recent.RecentsActivity"
Android 5.0 - 7.1: "com.android.systemui.recents.RecentsActivity" ("s" letter was added)
The best solution for you will be to utilize Accessibility Service.
Override onAccessibilityEvent() method, filter out ClassNames listed above and do something when you detect this event. For example simulate pressing the 'Home' button. You can do this by making a global action in Accessibility Service.
thanks esse for solution for higher SDK! I missed it.
But in my case I need to duplicate call (or effect is unstable)
if (SDK>15){
windowCloseHandler.postDelayed(windowCloserRunnable, 10);
windowCloseHandler.postDelayed(windowCloserRunnable, 300);
}
If you are interested in disabling all system buttons, may be the option would be to kill system bar completely, see Easy way to hide system bar on Android ICS

is it possible to hide the system bar

I created a launcher, to use it in an internal application. for some security reasons i would like to hide the system bar (the acces to the parameter an ordrer to the acces to installed application). But i have no idea how to do this.
Tablet that will be used are not rooted.
Can you help me please?
You can't hide it but you can disable it, except home. For that you can give your application as home category and let the user choose.
<category android:name="android.intent.category.HOME" />
Rest all can be disable.
add this in manifest.
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
inside onCreate()
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_home);
View v = findViewById(R.id.home_view);
v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
where home_view is the parent view of xml file.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
public void onWindowFocusChanged(boolean hasFocus)
{
try
{
if(!hasFocus)
{
Object service = getSystemService("statusbar");
Class<?> statusbarManager = Class.forName("android.app.StatusBarManager");
Method collapse = statusbarManager.getMethod("collapse");
collapse .setAccessible(true);
collapse .invoke(service);
}
}
catch(Exception ex)
{
}
}
You can hide the bottom bar I used this code to hide:
getWindow().getDecorView().setSystemUiVisibility(View.GONE);
use this code for android box with keyboard or remote.
Tablet that will be used are not rooted
Then you can't hide it. You can however use SYSTEM_UI_FLAG_HIDE_NAVIGATION to hide it temporary, but it will get visible once the user touches the screen:
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.
You can hide the navigation bar on Android 4.0 and higher using the SYSTEM_UI_FLAG_HIDE_NAVIGATION flag. This snippet hides both the navigation bar and the status bar:
View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions
See the following: Hiding the Navigation Bar
Put this in your onCreate() method:
requestWindowFeature(Window.FEATURE_NO_TITLE);
EDIT: Hiding the status bar would require your application be full screen or rooted.

Hide Tablet system bar

I want to hide system bar for tablet device. I searched a lot but not succeed. I added image for it.
I found some solution like
View v = findViewById(R.id.view_id);
v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
but I dont know how to use it
And I know that is possible as http://forum.xda-developers.com/showthread.php?t=1228046 Can any one know how to do this ?
Code snippet to show/hide status bar on rooted android tablets
To hide:
Process proc = null;
String ProcID = "79"; //HONEYCOMB AND OLDER
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
ProcID = "42"; //ICS AND NEWER
}
try {
proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "service call activity "+ProcID+" s16 com.android.systemui" });
} catch (Exception e) {
Log.w("Main","Failed to kill task bar (1).");
e.printStackTrace();
}
try {
proc.waitFor();
} catch (Exception e) {
Log.w("Main","Failed to kill task bar (2).");
e.printStackTrace();
}
To show:
Process proc = null;
try {
proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "am startservice -n com.android.systemui/.SystemUIService" });
} catch (Exception e) {
Log.w("Main","Failed to kill task bar (1).");
e.printStackTrace();
}
try {
proc.waitFor();
} catch (Exception e) {
Log.w("Main","Failed to kill task bar (2).");
e.printStackTrace();
}
Finally after searching lots of time I got some alternativ for my requirement.
I know this is not a good idea for a programmer to back off from this situation but for my time limit I used this way...
I found this link and application which fullfil my requirement
http://www.42gears.com/blog/2012/04/how-to-hide-bottom-bar-in-rooted-android-3-0-tablets-using-surelock/
please visit this once if you want this type of requirement in your application ....
Thanks to all for helping me in my problem...
It is not possible to hide the system bar. There is nothing in the API that allows for it. This is because the user always needs access to the home and back keys in case the app freezes or does something goofy where the user just needs to get out of the app. You can only hide the action bar.
There is a workaround to disable menu bar in all most all tablets without rooting. But this is bit tricky, but it works clean. Several well known apps in the market at the moment using this strategy to achieve this disable menu bar feature for their apps.
Grant admin privilege.
Set password & lock the device using device admin profile api
Then load what ever the UIs on top of the native lock screen. (Of course this will show background lock screen whenever a transition happens between activities. But if logic is organized well, then it will be smooth & less noticed by the user)
When need to enable back, reset password to "" using resetPassword("", 0) of device policy manager object.
var width = innerWidth;
var height = innerHeight;
I think this code will help for you.its not hide the tablet bar
but your application fit on any device you can use this
(I used this code in javascript for cord ova mobile application)
You just need combination of SYSTEM_UI_FLAG_IMMERSIVE_STICKY | SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. For example, if you use opengl and glSurfaceView is you surface:
glSurfaceView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Swipe at bottom to see the bottom bar, it will hide again after few seconds.
I believe its the same for all android devices.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
I also found another solution but this of course is just a separate app called surelock.
http://onkarsingh.sys-con.com/node/2184158
EDIT:
The above code doesn't hide the Tablet Bar. I'll leave my answer up for those looking to hide the System Bar in another Android Device.
You can't hide it but you can simply disable it, except home. Try this link. . Using SYSTEM_UI_FLAG_LOW_PROFILE you can dim your system bar and using onWindowFocusChanged() can take the focus and collapse it.
I found a trick on a galaxy tab for use it as a kiosk
according to the developer guide of Samsung
You can ask your app to be over the lock system and ask the return button to go back to a start activity/view of your app.
I done this for a web View app
#Override
public void onBackPressed() {
//here asking to go back to home page
mWebView.loadUrl(mHomepageUrl);
}
for asking to stay up from the lock system, on the onCreate method :
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
and then when you click on the power button twice , you found back your application , and only the back button is active on the status bar
So the only way is to reboot the tablet (and so you can use the classic lock system with a code to open tablet)
Can be useful if the power button is not accible by visitor , or if your are the only one who have the unlock code
// Put code on onCreate method of your activity / fragment
#Override
#SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
In order to create a Kiosk app in android you need the following:
- Override the onkeydown
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK || keyCode==KeyEvent.KEYCODE_HOME){
startActivity(new Intent(this,MainActivity.class));
return true;
}
return super.onKeyDown(keyCode, event);
}
Then make your activity a launcher activity in order to override the home button. (in the manifest)
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
No need for weird locker apps that asks a million permissions. You don't have to root your phone.

Categories

Resources