dtyler
dtyler

Reputation: 1428

Permanently hide Android Status Bar

I'm trying to hide the system Status Bar on an Android 4.4 device. This is for a kiosk-mode where my app will be the only app ever run on the device. The target device for now is a 2013 Nexus 7.

The device is rooted, and I've been able to completely remove the bottom Navigation Bar with some info from this post.

For the top Status Bar, everything I have tried only hides the bar temporarily. If my users motion down at the top of the screen, the status bar reappears. I don't want to allow them to see the time, get to settings or even see notifications.

Posts I've found and already tried:

Any suggestions?

Ideally, I'd love to be able to edit build.prop to do this, since I'm already doing that for the navigation bar, and could do this at the same time. I'm trying to not have to build my own android image.

Update:

After some more work, this seems to depend somewhat on the exact build of android, or the device its running on.

Some devices, such as the Nexus series I've been working with allow the user to swipe to make the bar reappear.

However, I've recently tried this on a Verizon Eclipse, and the bar does not reappear, which is what I was looking for.

I'm still looking for a better solution to target all devices, but it will probably come down to creating my own build of android.

Upvotes: 38

Views: 50397

Answers (9)

Luigi_Papardelle
Luigi_Papardelle

Reputation: 161

For rooted devices, I use the follwing code to change visibility from within my apps. It sets the visibility of the System UI and then reboots the device to make the setting changes actually happen. You can also use "pm "hide" com.android.systemui"... via adb, of course.

Please note that on some older devices, the command parameters were "enable" / "disable". For newer Android versions (9+), I observed that only "unhide" and "hide" were working for me.

fun setSystemUiEnabled(enabled: Boolean) {
    try {
        val p = Runtime.getRuntime().exec("su")
        val os = DataOutputStream(p.outputStream)
        os.writeBytes(
            "pm ${if (enabled) "unhide" else "hide"} com.android.systemui\n"
        )
        os.writeBytes("reboot\n")
        os.writeBytes("exit\n")
        os.flush()
    } catch (e: IOException) {
        Timber.w(e, "Error while setting system-ui enabled-state to $enabled")
        e.printStackTrace()
    }
}

Upvotes: 0

mojtaba
mojtaba

Reputation: 94

try this code:

disable statusbar and navbar

adb shell
su 
pm disable com.android.systemui
reboot

enable statusbar and navbar

adb shell
su 
pm enable com.android.systemui
reboot

It works on Android 5.1.1 but the usb camera is down

Another way (my device worked without any problems)

Remove System Navigation Bar ¶ The Android System Navigation Bar is the bar at the bottom of the screen which presents the back, home, and app-switch soft-keys.

As the system navigation bar is independent from any installed Android application in particular, removing it is done in the Android OS.

To accomplish this on a rooted installed device you can set the qemu.hw.mainkeys property to 1 by editing /system/build.prop:

qemu.hw.mainkeys=1

To accomplish this at build time you would set the 'config_showNavigationBar' value to false in your device overlay (ie device/gateworks/ventana/overlay/frameworks/base/core/res/res/values/config.xml):

<bool name="config_showNavigationBar">false</bool>

Note you could also make build.prop modifications at build time by adding to the PRODUCT_DEFAULT_PROPERTY_OVERRIDES or ADDITIONAL_BUILD_PROPERTIES variables which can be found in your device target configuration (ie imx6.mk and BoardConfig.mk in device/gateworks/ventana/).

Additionally, you can hide the navigation bar (and status bar) within an application by setting the SYSTEM_UI_FLAG_HIDE_NAVIGATION flag however it will pop back if the user touches anywhere on the screen. http://trac.gateworks.com/wiki/Android/Kiosk

Upvotes: 1

AvielNiego
AvielNiego

Reputation: 1233

I've used this answer to hide the softkeys: https://stackoverflow.com/a/27003890/1525867

And for disabling the StatusBar (this may harm your device so do it carfully. I've ruined my device several times before I managed to do it) Tested on Asus Tinker Board, Android 6:

  • Download apktool from here https://bitbucket.org/iBotPeaches/apktool/downloads/ and add it to pathin your favorite way
  • pull SystemUI.apk from your device: adb pull /system/priv-app/SystemUI/SystemUI.apk the path to SystemUI.apk may be different

  • pull framework-res.apk from your device adb pull /system/framework/framework-res.apk the path to framework-res.apk may be different

  • run apktool if framework-res.apk

  • run apktool if SystemUI.apk

  • run apktool d SystemUI.apk

  • Open SystemUI\res\layout\status_bar.xml and add android:visibility="gone" to the top most xml element (for me it was com.android.systemui.statusbar.phone.PhoneStatusBarView)

  • run apktool b SystemUI

  • Go to SystemUI\original and copy AndroidManifest.xml and META-INF to SystemUI\build\apk\

  • run apktool b SystemUI again

  • Go to SystemUI\dist\ and override the device's original SystemUI.apk with the one at SystemUI\dist\SystemUI.apk with adb push SystemUI\dist\SystemUI.apk /system/priv-app/SystemUI/SystemUI.apk

  • Restart device

Based on this thread https://forum.xda-developers.com/showthread.php?t=2203166

Upvotes: 4

D. Gibbs
D. Gibbs

Reputation: 560

I know this is an old question but hopefully it will help someone. Here are two very simple calls to disable and enable the status bar that I have used before. Can be used from the command line or executed by a Java app:

Disable:

service call activity 42 s16 com.android.systemui

Enable:

am startservice -n com.android.systemui/.SystemUIService

Upvotes: 19

Abhimaan
Abhimaan

Reputation: 1911

We could not prevent the status appearing in full screen mode in kitkat devices, so made a hack which still suits the requirement ie block the status bar from expanding.

For that to work, the app was not made full screen. We put a overlay over status bar and consumed all input events. It prevented the status from expanding.

note:

  • customViewGroup is custom class which extends any layout(frame,relative layout etc) and consumes touch event.
  • to consume touch event override the onInterceptTouchEvent method of the view group and return true

Updated

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

customViewGroup implementation Code :

WindowManager manager = ((WindowManager) getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = 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;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (50 * getResources()
            .getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    customViewGroup view = new customViewGroup(this);

    manager.addView(view, localLayoutParams);

Hope this helps you

Upvotes: 28

Muhammed Refaat
Muhammed Refaat

Reputation: 9103

A great solution I found for that issue, setting each Activity theme & windowSoftInputMode to the following values :

<activity   android:name=".MyActivity"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 
            android:windowSoftInputMode="adjustResize">  <!-- theme : to set the activity to a full screen mode without a status bar(like in some games) -->
</activity>                                              <!-- windowSoftInputMode : to resize the activity so that it fits the condition of displaying a softkeyboard -->

for more info refer here.

Upvotes: 2

dtyler
dtyler

Reputation: 1428

I did try the workaround provided by @gonglong, but I wasn't happy with the result because of a flash in the UI as the workaround kicked in.

Instead, I was able to do this as root:

settings put secure user_setup_complete 0

I think on a normal device, this would cause the initial device setup to start, but on my devices, I've removed that APK from system so that doesn't happen.

This isn't documented anywhere I can find, but has a nice effect, where the top settings UI can't be dragged down. The notifications area can still be dragged down.

Another setting that I found useful was:

settings put global device_provisioned 0

This hides the Airplane Mode and Silent Mode options from the Power menu, which is an added bonus for my application.

There might be more side effects, but I've yet to find any that matter to me.

Full List

This list was taken from a Nexus 7 2013 LTE running brand new Android 4.4.3 (KTU84L). The number in square brackets is the value when I pulled the db file, which was after basic setup device setup and enabling developer/USB, but before making any other changes in settings

This file was found at data/data/com.android.providers.settings/databases/settings.db

Note: Some URLS required adding an extra space character to bypass SO filters

system namespace

  • volume_music [11]
  • volume_ring [5]
  • volume_system [7]
  • volume_voice [4]
  • volume_alarm [6]
  • volume_notification [5]
  • volume_bluetooth_sco [7]
  • mode_ringer_streams_affected [174]
  • mute_streams_affected [46]
  • vibrate_when_ringing [0]
  • dim_screen [1]
  • dtmf_tone_type [0]
  • hearing_aid [0]
  • tty_mode [0]
  • screen_brightness [87]
  • screen_brightness_mode [1]
  • window_animation_scale [1.0]
  • transition_animation_scale [1.0]
  • accelerometer_rotation [1]
  • haptic_feedback_enabled [1]
  • notification_light_pulse [1]
  • dtmf_tone [1]
  • sound_effects_enabled [1]
  • lockscreen_sounds_enabled [1]
  • pointer_speed [0]
  • alarm_alert [content://media/internal/audio/media/11]
  • notification_sound [content://media/internal/audio/media/27]
  • ringtone [content://media/internal/audio/media/35]
  • next_alarm_formatted []
  • radio.data.stall.recovery.action [0]
  • screen_off_timeout [30000]

global namespace

  • airplane_mode_on [0]
  • airplane_mode_radios [cell,bluetooth,wifi,nfc,wimax]
  • airplane_mode_toggleable_radios [bluetooth,wifi,nfc]
  • auto_time [1]
  • auto_time_zone [1]
  • stay_on_while_plugged_in [0]
  • wifi_sleep_policy [2]
  • mode_ringer [2]
  • package_verifier_enable [1]
  • wifi_networks_available_notification_on [1]
  • bluetooth_on [0]
  • cdma_cell_broadcast_sms [1]
  • data_roaming [0]
  • mobile_data [1]
  • netstats_enabled [1]
  • install_non_market_apps [0]
  • usb_mass_storage_enabled [1]
  • wifi_max_dhcp_retry_count [9]
  • wifi_display_on [0]
  • lock_sound [/system/media/audio/ui/Lock.ogg]
  • unlock_sound [/system/media/audio/ui/Unlock.ogg]
  • power_sounds_enabled [1]
  • low_battery_sound [/system/media/audio/ui/LowBattery.ogg]
  • dock_sounds_enabled [0]
  • desk_dock_sound [/system/media/audio/ui/Dock.ogg]
  • desk_undock_sound [/system/media/audio/ui/Undock.ogg]
  • car_dock_sound [/system/media/audio/ui/Dock.ogg]
  • car_undock_sound [/system/media/audio/ui/Undock.ogg]
  • wireless_charging_started_sound [/system/media/audio/ui/WirelessChargingStarted.ogg]
  • dock_audio_media_enabled [1]
  • set_install_location [0]
  • default_install_location [0]
  • emergency_tone [0]
  • call_auto_retry [0]
  • preferred_network_mode [9]
  • subscription_mode [1]
  • low_battery_sound_timeout [3600000]
  • wifi_watchdog_on [1]
  • audio_safe_volume_state [1]
  • send_action_app_error [1]
  • web_autofill_query_url [http:// android.clients.google.com/proxy/webautofill]
  • sms_short_codes_content_url [http://www.gstatic.com/android/config_update/07172013-sms-blacklist.txt]
  • sms_short_codes_metadata_url [http://www.gstatic.com/android/config_update/07172013-sms-metadata.txt]
  • cert_pin_metadata_url [http://www.gstatic.com/android/config_update/10142013-metadata.txt]
  • cert_pin_content_url [http://www.gstatic.com/android/config_update/10142013-pins.txt]
  • wifi_on [1]
  • assisted_gps_enabled [1]
  • wifi_scan_always_enabled [1]
  • device_provisioned [1]
  • bugreport_in_power_menu [0]
  • development_settings_enabled [1]
  • adb_enabled [1]
  • wifi_country_code [us]

secure namespace

  • wifi_watchdog_watch_list [GoogleGuest]
  • mock_location [0]
  • backup_enabled [0]
  • backup_transport [com.google.android.backup/.BackupTransportService]
  • mount_play_not_snd [1]
  • mount_ums_autostart [0]
  • mount_ums_prompt [1]
  • mount_ums_notify_enabled [1]
  • accessibility_script_injection [0]
  • accessibility_web_content_key_bindings [0x13=0x01000100; 0x14=0x01010100; 0x15=0x02000001; 0x16=0x02010001; 0x200000013=0x02000601; 0x200000014=0x02010601; 0x200000015=0x03020101; 0x200000016=0x03010201; 0x200000023=0x02000301; 0x200000024=0x02010301; 0x200000037=0x03070201; 0x200000038=0x03000701:0x03010701:0x03020701;]
  • long_press_timeout [500]
  • touch_exploration_enabled [0]
  • speak_password [0]
  • accessibility_script_injection_url [https://ssl.gstatic.com/accessibility/javascript/android/AndroidVox_v1.js]
  • lockscreen.disabled [0]
  • screensaver_enabled [1]
  • screensaver_activate_on_dock [1]
  • screensaver_activate_on_sleep [0]
  • screensaver_components [com.google.android.deskclock/com.android.deskclock.Screensaver]
  • screensaver_default_component [com.google.android.deskclock/com.android.deskclock.Screensaver]
  • accessibility_display_magnification_enabled [0]
  • accessibility_display_magnification_scale [2.0]
  • accessibility_display_magnification_auto_update [1]
  • android_id [a0ef8b2a9ade982c]
  • enabled_input_methods [com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME:com.google.android.googlequicksearchbox/com.google.android.voicesearch.ime.VoiceInputMethodService]
  • input_methods_subtype_history []
  • selected_input_method_subtype [-1]
  • selected_spell_checker [com.google.android.inputmethod.latin/com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService]
  • selected_spell_checker_subtype [0]
  • lock_screen_owner_info_enabled [0]
  • voice_recognition_service [com.google.android.googlequicksearchbox/com.google.android.voicesearch.serviceapi.GoogleRecognitionService]
  • default_input_method [com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME]
  • enabled_print_services [com.google.android.apps.cloudprint/com.google.android.apps.cloudprint.printdialog.services.CloudPrintService:com.hp.android.printservice/com.hp.android.printservice.ServiceAndroidPrint]
  • enabled_on_first_boot_system_print_services [com.google.android.apps.cloudprint/com.google.android.apps.cloudprint.printdialog.services.CloudPrintService:com.hp.android.printservice/com.hp.android.printservice.ServiceAndroidPrint]
  • bluetooth_name [Nexus 7]
  • masterLocationPackagePrefixBlacklist [com.google.,com.semaphoremobile.zagat.android]
  • serial_blacklist [827,864]
  • dropbox:data_app_anr [disabled]
  • dropbox:data_app_wtf [disabled]
  • ssl_session_cache [file]
  • pubkey_blacklist [5f3ab33d55007054bc5e3e5553cd8d8465d77c61,783333c9687df63377efceddd82efa9101913e8e]
  • facelock_liveliness_recognition_threshold [2.2]
  • facelock_detection_threshold [0.0]
  • dropbox:data_app_crash [disabled]
  • masterLocationPackagePrefixWhitelist [com.google.android.gms]
  • lockscreen.options [enable_facelock]
  • facelock_max_center_movement [10.0]
  • bluetooth_address [AC:22:0B:A5:AF:3D]
  • bluetooth_addr_valid [1]
  • config_update_certificate [ truncated base64 content ]
  • location_providers_allowed [gps,network]
  • allowed_geolocation_origins [http://www.google.co.uk http:// www.google.com]
  • locationPackagePrefixBlacklist []
  • user_setup_complete [1]
  • locationPackagePrefixWhitelist []
  • last_setup_shown [eclair_1]

Upvotes: 22

gonglong
gonglong

Reputation: 592

I don't have a perfect solution but a workaround here. The basic idea is to listen the system ui status changes and force navigation/status bar as invisible. It takes effect as similar as setting IMMERSIVE_STICKY mode but disappearing navigation/status bar quicker than IMMERSIVE_STICKY.

here it is:

set system ui style in onCreate() and on onResume function, and set system ui change listener

    mDecroView.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);
    mDecroView.setOnSystemUiVisibilityChangeListener(this);

force system bar as invisible in onSystemUiVisibilityChange, setting system ui some seconds later otherwise it would take on effect(does not know exactly why, maybe system just ignores the system ui setting request when system bar showing not yet completed)

    public void onSystemUiVisibilityChange(int visibility) {
    // TODO Auto-generated method stub
    Log.d(TAG, "onSystemUiVisibilityChange called with visibility " + visibility);
    if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0){
        if(null == mHandler){
            mHandler = new MyHandler();
        }
        if(null != mHandler){
            mHandler.removeMessages(MSG_HIDE_SYSTEM_BAR);
            mHandler.sendEmptyMessageDelayed(MSG_HIDE_SYSTEM_BAR, 50);
        }
        //the deccro view is not in full screen
        Log.d(TAG, "setSystemUiVisibility");
        Log.d(TAG, "current system ui is " + mDecroView.getSystemUiVisibility());


    }
}

then you can set system ui like this:

public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        super.handleMessage(msg);
        switch(msg.what){
        case MSG_HIDE_SYSTEM_BAR:
                           mDecroView.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);
            break;
        }
    }

Upvotes: 2

DiegoAlt
DiegoAlt

Reputation: 89

add this before : setContentView(R.layout.x);

this.requestWindowFeature(Window.FEATURE_NO_TITLE);    // Removes title bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                 
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.x);

Upvotes: -1

Related Questions