32

在 Android 2.3 及更低版本中,您可以使应用程序全屏显示,然后通过仅返回 false onKeyDown()... 并将应用程序注册为默认主页启动器应用程序来“劫持”菜单/返回/搜索按钮,这样,没有办法退出应用程序。

在 Android 3.0 (Honeycomb) 中,导航按钮(系统栏)始终存在,我想隐藏它。可能吗?

仅供参考,我不会在 Android Market 上发布此应用程序。这是将在内部使用的设备的内部应用程序,我需要保护设备。

4

11 回答 11

31

由于使用公共 API 无法做到这一点,因此我找到了一种以非常“hack-ish”的方式进行操作的方法,该方法需要有根设备。

更新:正如 user864555 指出的那样,这是另一种解决方案

$ 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

“该代码禁用应用程序 SystemUI,它是实际的菜单栏。修改后,您还将获得该系统栏的空间。但请确保有一个后退按钮或退出按钮。”

这也很好用。请投票给他的答案。我会尽量保持这个更新。


更新:这是第三种方法。一种以编程方式或使用命令行的方法。在这里找到:http ://android.serverbox.ch/?p=306

此方法需要 root 访问权限,但您无需更改 LCD 密度,保持与原始相同,您可以快速轻松地恢复 UI 导航栏,而无需每次都重新启动。

博客文章还展示了如何在您的 Android 应用程序上实现它,记住它需要 root,除非您的应用程序在 kiosk 或您自己的设备上运行,否则这样做可能不是一个好主意,请不要在在 Android 市场或任何公共场所发布的应用程序。

要停止/删除/禁用系统栏(在发出此命令之前需要 su):

$ service call activity 79 s16 com.android.systemui

要恢复系统栏,只需发出以下命令:

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

就这么容易。希望 ICS 与源代码一起尽快发布,以便任何人都可以为我们的 Kiosk 平板电脑构建 Android。

于 2011-05-10T20:54:01.860 回答
11

您无法在 Android 3.0 上隐藏系统栏。

于 2011-02-24T22:44:25.590 回答
7

如果您可以访问系统文件,则可以执行此操作(我的已解锁并已植根,所以我不确定您需要什么,我还没有尝试过使用工厂新鲜的 xoom):

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

该代码禁用应用程序 SystemUI,它是实际的菜单栏。通过该修改,您还将获得该系统栏的空间,但请确保您的应用中有后退按钮或退出按钮。

编辑:

如果您对只读文件有问题,您需要将/system目录挂载为读写。为此,请在 adb shell 中使用此命令(来源: http: //forum.xda-developers.com/showthread.php? t=1159495&page=5 )

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

您可以使用该命令将其重新安装为只读:

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

编辑:

这种方法可以让软键盘在需要的时候正常显示。

于 2011-07-29T08:59:18.673 回答
1

这是与我之前的答案相关的代码。它会自动隐藏状态栏并在完成后再次显示。重要提示:要再次显示它,代码必须重新启动 system_server 这需要一些时间才能再次启动,在此期间,您将看到蜂窝启动动画。这是我现在找到的唯一再次显示状态栏的方法。重启 SystemUI 是不够的。因此,它会在重新启动 system_server 时关闭您的应用程序。

此代码需要安装了超级用户的根操作系统。

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();
    }
}
于 2011-07-29T21:58:10.187 回答
0

应用程序HideBar可用于隐藏 android 平板电脑(HC、ICS、JB)上的系统栏。它包含一个可选的信息亭模式,可用于完全锁定平板电脑以及其他选项,如隐藏的后退按钮。它是 GPL 软件。如果必须大量安装此应用程序,请联系开发人员(我,请参阅应用程序网站上的电子邮件)。

于 2012-07-31T10:51:01.770 回答
0

是的,如果您在设备上具有 root 访问权限,则可以这样做。

此代码可以通过杀死它的进程并再次调用它来隐藏和显示状态栏。

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;

        }
    }


}
于 2014-12-10T18:14:42.770 回答
0

对于遇到此问题的其他人:

如果您没有在 AndroidManaifest.xml 文件中正确设置 android:targetSdkVersion,则 setSystemUiVisibility 无效(与其他高级 API 不同,无论是否正确设置了 targetSDKVersion)。

我不小心将我的 targetSdkVersion 设置为 8。将其提高到 16 立即导致 setSystemUIVisiblity 产生了预期的效果。

于 2012-10-08T22:07:54.713 回答
0

从 4.4 开始,您可以这样做(这个问题很老,但总是出现在这个话题上):

setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE)

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

于 2015-02-03T02:11:56.543 回答
0

虽然这不能回答“锁定”屏幕的问题,但您可以使用 setSystemUiVisibillity api(API 级别 11)隐藏状态栏而无需成为 root。

一些伪代码:

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?
                }
            }
        });
    }
}

这将隐藏状态栏,直到用户单击屏幕的下边缘,在这种情况下,状态栏将被显示(它会在几秒钟后再次隐藏)。

确保您在清单中指定了 targetSdkVersion="11" 或更高版本。

于 2011-12-08T21:27:44.403 回答
-1

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

或者

mainView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE)

不,任务栏还在,用三个灰点代替经典图标

于 2013-03-30T01:12:54.860 回答
-1

如果您想在整个应用程序中隐藏导航栏,那么这是最简单的方法。只需在清单文件中的应用程序标记中写入此代码

> <Application
> android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" <!--
> other parameters of application tag-->
> >
于 2013-03-26T06:42:04.780 回答