在Android 2.3及以下版本,您可以使应用程序全屏,然后通过仅返回false onKeyDown()来“劫持”菜单/后退/搜索按钮...并将应用程序注册为默认的主屏幕启动器应用程序,这样就没有退出应用程序的方式。
在Android 3.0(Honeycomb)中,导航按钮(系统栏)始终存在,我想隐藏它。是否可能?
顺便说一下,我不会在Android Market上发布此应用程序。这是一个内部应用程序,专门为将要在内部使用的设备而设计的。我需要保护设备安全。
在Android 2.3及以下版本,您可以使应用程序全屏,然后通过仅返回false onKeyDown()来“劫持”菜单/后退/搜索按钮...并将应用程序注册为默认的主屏幕启动器应用程序,这样就没有退出应用程序的方式。
在Android 3.0(Honeycomb)中,导航按钮(系统栏)始终存在,我想隐藏它。是否可能?
顺便说一下,我不会在Android Market上发布此应用程序。这是一个内部应用程序,专门为将要在内部使用的设备而设计的。我需要保护设备安全。
由于公共API无法实现此操作,我找到了一种非常“hack-ish”的方法来实现它,需要使用rooted设备。
更新:正如用户864555所指出的,这是另一种解决方案
$ 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权限,除非您的应用程序运行在信息亭或自己的设备上,否则不要在已发布在Android市场或任何公共场合的应用程序上实施此方法。
停止/删除/禁用系统栏(在发出此命令之前需要su):
$ service call activity 79 s16 com.android.systemui
要恢复系统栏,只需执行以下命令:
$ am startservice -n com.android.systemui/.SystemUIService
就这么简单。希望ICS尽快发布并附带源代码,这样任何人都可以为我们的Kiosk平板建立Android。
在 Android 3.0 上,您无法隐藏系统栏。
adb shell
cd /system/app/
mv SystemUI.odex SystemUI.odexold
mv SystemUI.apk SystemUI.apkold
exit
adb reboot
mount -o remount,rw /dev/block/stl6 /system
mount -o remount,ro [文件系统路径]
mount -o remount,ro /dev/block/stl6 /system
这些方法允许在需要时正常显示软键盘。
这里是与我之前回答相关的代码。它会自动隐藏状态栏,并在完成后再次显示出来。重要提示:为了再次显示它,代码必须重新启动system_server,这需要一些时间来重新启动,而在此期间,您将看到蜂窝引导动画。目前这是我找到的唯一方法来再次显示状态栏。重新启动SystemUI不足以解决问题。因此,在重新启动system_server时,它将关闭您的应用程序。
此代码需要已安装超级用户的rooted操作系统。
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();
}
}
虽然这并没有回答关于“锁定”屏幕的问题,但您可以使用setSystemUiVisibility 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"或更高版本。
应用程序HideBar可用于隐藏Android平板电脑(HC,ICS,JB)上的系统栏。它包含一个可选的展示模式,可用于完全锁定平板电脑,以及其他选项,如隐藏返回按钮。它是GPL软件。如果需要大量安装此应用程序,请联系开发人员(即我,在应用程序网站上查看电子邮件)。
从4.4版本开始,您可以这样做(这个问题很老,但总是在这个主题上出现):
setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE)
https://developer.android.com/training/system-ui/immersive.html
对于其他遇到这个问题的人:
如果您在AndroidManifest.xml文件中没有正确设置android:targetSdkVersion,那么setSystemUiVisibility将无效(与其他高级API不同,它们无论是否正确设置了targetSDKVersion都可以正常工作)。
我不小心将我的targetSdkVersion保留在8。将其提升到16立即使setSystemUIVisiblity产生了预期的效果。
如果您在设备上拥有 root 访问权限,是可以做到的。
通过终止 StatusBar 的进程并重新调用它,这段代码可以隐藏和显示 StatusBar。
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;
}
}
}
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen
或者
mainView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE)
不,任务栏仍然存在,但使用三个灰点代替经典图标。