开发者

Is there a way to hide the system bar in Android 3.0? It's an internal device and I'm managing navigation

开发者 https://www.devze.com 2023-02-13 12:02 出处:网络
In Android 2.3 and below, you could make an application full screen, and then \"hijack\" the menu/back/search buttons by just returning false onKeyDown()... and registering the app as a default home l

In Android 2.3 and below, you could make an application full screen, and then "hijack" the menu/back/search buttons by just returning false onKeyDown()... and registering the app as a default home launcher applicati开发者_开发知识库on, that way, there's no way to exit the application.

In Android 3.0 (Honeycomb) the navigation buttons (System Bar) is always present, I'd like to hide it. Is it possible?

FYI, I am not publishing this application on the Android Market. This is an internal application for devices that are going to be used internally, I need to secure the device.


Since this is not possible to do using a public API, I have found a way to do it in a very "hack-ish" way that requires a rooted device.

Update: as user864555 pointed below, this is another solution

$ adb remount
$ adb shell mv /system/app/SystemUI.odex /system/app/SystemUI.odexold
$ adb shell mv /system/app/SystemUI.apk /system/app/SystemUI.apkold
$ adb reboot

"That code disable the app SystemUI which is the actually menu bar. Which that modification, you will also gain the space of that system bar. But make sure to have a back button or something to exit."

That works great as well. Please vote for his answer. I will try to keep this one updated as much as I can.


Update: Here's a third method. A way to do it programmatically or using the command line. Found here: http://android.serverbox.ch/?p=306

This method requires root access, but you don't need to change the LCD Density, keeping the same as the original, and you can get the UI nav bar back really quick and easy without having to reboot everytime.

The blog post also shows how to implement it on your Android application, remember it requires root, and it might not be a great idea to do so unless your application is running on a kiosk or your own device, please do not implement this method on an app that's published in the Android market or anywhere public.

To stop/remove/disable the system bar (need to be su before issuing this command):

$ service call activity 79 s16 com.android.systemui

To restore the system bar just simply issue this command:

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

It's that easy. Hopefully ICS gets released soon along with the source code so that anyone can build Android for our Kiosk tablets.


You cannot hide the system bar on Android 3.0.


If you have access to system file, you can do this (mine is unlocked and rooted, so i'm not sure what you need, I haven't tried with a factory fresh xoom):

adb shell
cd /system/app/
mv SystemUI.odex SystemUI.odexold
mv SystemUI.apk SystemUI.apkold
exit
adb reboot

That code disable the app SystemUI which is the actually menu bar. With that modification, you will also gain the space of that system bar, but make sure that you have a back button or something to exit in your app.

Edit:

If you have problems with read-only file, you mint need to mount the /system directory as read-write. To do so, use this command in adb shell (Source: http://forum.xda-developers.com/showthread.php?t=1159495&page=5)

mount -o remount,rw /dev/block/stl6 /system

You can remount it as read-only using that command:

mount -o remount,ro /dev/block/stl6 /system

Edit:

This methods allow the soft keyboard to be displayed normally when needed.


Here is related code with my previous answer. It automatically hide the status bar and show it back again when finish. Important: to show it back again, the code have to restart system_server which take some time to boot again and during that time, you will see the honeycomb booting animation. That's the only I find for now to show the statusbar again. Restarting SystemUI is not enought. And because of that, it will shutdown your app when restart system_server.

This code need a rooted os with superuser installed on.

package com.projects;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TableLayout.LayoutParams;

// http://www.stealthcopter.com/blog/2010/01/android-requesting-root-access-in-your-app/
public class FullScreenTestActivity extends Activity implements Button.OnClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try
        {
            Process p;
            p = Runtime.getRuntime().exec("su"); 

            // Attempt to write a file to a root-only
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            os.writeBytes("mount -o remount,rw /dev/block/stl6 /system\n");
            os.writeBytes("mv /system/app/SystemUI.odex /system/app/SystemUI_Old.odex\n");
            os.writeBytes("mv /system/app/SystemUI.apk /system/app/SystemUI_Old.apk\n");
            os.writeBytes("mount -o remount,ro /dev/block/stl6 /system\n");

            // Close the terminal
            os.writeBytes("exit\n");
            os.flush();
            p.waitFor();

            new AlertDialog.Builder(this)
                .setIconAttribute(android.R.attr.alertDialogIcon)
                .setMessage("Android Honeycomb StatusBar removed successfully!")
                .show();

            // Set action for exiting.
            Button cmdExit = new Button(this);
            cmdExit.setText("Exit");
            cmdExit.setOnClickListener(this);
            this.addContentView(cmdExit, new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
        }
        catch (Exception e)
        {
            ShowErrorGlobal(e);
        }
    }

    public void onClick(View v) {
        try
        {
            Process p;
            p = Runtime.getRuntime().exec("su"); 

            // Attempt to write a file to a root-only
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            os.writeBytes("mount -o remount,rw /dev/block/stl6 /system\n");
            os.writeBytes("mv /system/app/SystemUI_Old.odex /system/app/SystemUI.odex\n");
            os.writeBytes("mv /system/app/SystemUI_Old.apk /system/app/SystemUI.apk\n");
            os.writeBytes("mount -o remount,ro /dev/block/stl6 /system\n");
            String systemServerPID = GetSystemServerPID();
            if (systemServerPID != null)
                os.writeBytes("kill " + systemServerPID + "\n");
            // else ... manual reboot is required if systemServerPID fail.

            // Close the terminal
            os.writeBytes("exit\n");
            os.flush();
            p.waitFor();
        }
        catch (Exception e)
        {
            ShowErrorGlobal(e);
        }
    }

    public String GetSystemServerPID()
    {
        try
        {
            Process p = Runtime.getRuntime().exec("ps -n system_server"); 
            p.waitFor();

            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            reader.readLine(); // Skip header.
            return reader.readLine().substring(10, 16).trim();
        }
        catch (Exception e)
        {
            return null;
        }
    }

    protected void ShowErrorGlobal(Exception e)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream stream = new PrintStream( baos );
        e.printStackTrace(stream);
        stream.flush();

        new AlertDialog.Builder(this)
            .setIconAttribute(android.R.attr.alertDialogIcon)
            .setTitle("Epic fail")
            .setMessage("Error: " + new String( baos.toByteArray() ))
            .show();
    }
}


Although this doesn't answer the question of 'locking' the screen, you can hide the status bar without being root by using the setSystemUiVisibillity api(API level 11).

Some pseudocode:

public MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstance) {
        //...
        final View mainView = findViewById(R.id.you_main_view_id);
        mainView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);

        //Register a listener for when the status bar is shown/hidden:
        final Context context = getApplicationContext();
        mainView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener () {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                if ((visibility == View.SYSTEM_UI_FLAG_VISIBLE)) {
                    //Do stuff here...pause the video/game?
                } else {
                    //Do other stuff here..resume the video/game?
                }
            }
        });
    }
}

This will hide the status bar until the user clicks along the lower edge of the screen, in which case the status bar will get shown (it'll get hidden again after a few seconds).

Make sure you've specified targetSdkVersion="11" or higher in your manifest.


The application HideBar can be used to hide the system bar on android tablets (HC, ICS, JB). It contains an optional kiosk mode that can be used to lock down tablets completely and also other options like a hidden back button. It is GPL software. Contact the developer (me, see email on applications website) if this application has to be installed in large volumes.


For others who have had this problem:

If you haven't set the android:targetSdkVersion properly in your AndroidManaifest.xml file, setSystemUiVisibility has no effect (unlike other advanced APIs which work whether or not the targetSDKVersion has been set properly or not).

I had accidentally left my targetSdkVersion at 8. Bumping it up to 16 immediately caused setSystemUIVisiblity to have the desired effect.


Yes it is possible to do if you have root access on the device.

This code can hide and show the StatusBar by killing it`s proccess and calling it back again.

package com.example.statusbar;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class MainActivity extends Activity {

    String commandToExecute;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        commandToExecute = "/system/xbin/su";
        executeShellCommand(commandToExecute);

        Button btHideStatusBar = (Button) findViewById(R.id.buttonHide);
        Button btShowStatusBar = (Button) findViewById(R.id.buttonShow);


        btHideStatusBar.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                commandToExecute = "/system/xbin/su -c /system/bin/service call activity 42 s16 com.android.systemui";
                executeShellCommand(commandToExecute);

            }
        });

    btShowStatusBar.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            commandToExecute = "/system/xbin/su -c /system/bin/am startservice -n com.android.systemui/.SystemUIService";
            executeShellCommand(commandToExecute);

        }
    });

    }

    private boolean executeShellCommand(String command) {
        try {

            Runtime.getRuntime().exec(command);

            return true;
        } catch (Exception e) {
            return false;

        }
    }


}


As of 4.4 you can do this (this question is very old, but always comes up on this topic):

setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE)

https://developer.android.com/training/system-ui/immersive.html


if you want to hide navigation bar through out the application then here is the most simplest way. just write this code in your application tag in manifest file

> <Application
> android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" <!--
> other parameters of application tag-->
> >


android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen

or

mainView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE)

No, the task bar is still there, with three gray dots instead classic icons

0

精彩评论

暂无评论...
验证码 换一张
取 消