如何在Android中禁用“主页”和其他系统按钮?


80

我需要在Android应用程序中禁用“主页”和其他系统按钮。

例如: MX Player见谷歌播放) -你可以按在播放器屏幕上“锁”图标,并锁定所有的硬件和软件系统的按钮。

它可以正常工作而无需生根。

我在具有不同Android版本的某些设备上进行了测试。我试图拆卸儿童锁(插件),但尚不知道它如何工作。

我需要用于儿童锁(插件)的相同解决方案MX Player:-禁用主页,后退和所有其他系统按钮。

有什么建议么?


1
stackoverflow.com/questions/17183905/…。您不能禁用主页按钮。
Raghunandan

2
@ user1024您是否找到问题的解决方案?因为我也想做与MX Player中相同的功能。
Chirag Shah 2013年

2
MX Player的方式很有趣。他们实际上压制了导航栏的返回。
nhaarman 2014年

您是否找到解决此问题的方法?我还需要弄清楚如何禁用这些按钮。至少,我该如何管理多任务按钮。
portfoliobuilder

您可以检查一下我的答案,我认为它将帮助您实现所需的目标stackoverflow.com/a/28603790/3300883
Miguel

Answers:


91

首先,如果您确实想为此禁用Home按钮或任何其他按钮(例如,Back按钮),请认真考虑,这不是应该做的事情(至少在大多数情况下,这是一个糟糕的设计) )。我只能说说自己的话,但是如果我下载的应用程序不允许我单击操作系统按钮等操作,那么接下来要做的就是卸载该应用程序并留下非常不好的评价。我也相信您的应用不会在App Store中出现。

现在...

请注意,它MX Player正在寻求在其他应用程序之上绘制的权限:MX Player权限
由于您无法覆盖设备Home上的按钮Android(在最新的OS版本中至少没有此按钮)。MX Player当您“锁定”应用程序并单击Home按钮时,它会在启动器顶部绘制自身。
要了解一个简单易懂的示例,可以查看Facebook Messenger App

当要求我提供有关MX PlayerStatus BarNavigation Bar“覆盖”的更多信息时,我正在编辑答案以也包括这些主题。

首先,MX Player在上使用沉浸式全屏模式DevBytes VideoKitKat
Android 4.4(API级别19)为setSystemUiVisibility()引入了新的SYSTEM_UI_FLAG_IMMERSIVE标志,可让您的应用真正进入“全屏”状态。将此标志与SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN标志结合使用时,将隐藏导航和状态栏,并让您的应用捕获屏幕上的所有触摸事件。

启用沉浸式全屏模式后,您的活动将继续接收所有触摸事件。用户可以沿着系统栏通常出现的区域向内滑动来显示系统栏。这将清除SYSTEM_UI_FLAG_HIDE_NAVIGATION标志(和SYSTEM_UI_FLAG_FULLSCREEN标志(如果已应用)),因此系统栏变得可见。如果设置,这也会触发View.OnSystemUiVisibilityChangeListener。但是,如果您希望系统栏在几分钟后自动再次隐藏,则可以使用SYSTEM_UI_FLAG_IMMERSIVE_STICKY标志。请注意,该标志的“粘性”版本不会触发任何侦听器,因为在此模式下临时显示的系统栏处于过渡状态。

第二:隐藏状态栏
第三:隐藏导航栏
请注意,尽管仅使用沉浸式全屏显示KitKat,但隐藏Status BarNavigation Bar不仅用于KitKat

关于第二和第三我没什么好说的,我相信你的想法,无论如何这都是快速阅读。只要确保您密切注意View.OnSystemUiVisibilityChangeListener即可

我添加了一个Gist解释了我的意思,它并不完整,需要一些修复,但是您会明白的。https://gist.github.com/Epsiloni/8303531

祝您实施愉快,并玩得开心!


1
那么,它如何隐藏导航栏并防止在触摸屏幕时再次弹出呢?当您进行滑动动作以退出沉浸式模式时,导航栏将立即显示并再次隐藏。此外,即使“沉浸式滑动”强制显示状态栏,锁定时也无法拉出通知面板。它是如何做到的?
nhaarman 2014年

2
好的,这很有帮助,但是我们还没有到那儿。我要发表两条评论,一条是对奇巧的评论,一条是对果冻豆的评论。对于奇巧,用标志TYPE_SYSTEM_ALERTSYSTEM_UI_FLAG_HIDE_NAVIGATION并且SYSTEM_UI_FLAG_IMMERSIVE_STICKY,没有退出应用程序的方式。两个系统栏均保持隐藏状态。除非打开电源菜单。然后,再次出现导航栏,主页按钮变为可用。在这种情况下,MX Player设法使导航栏保持隐藏。因此,对于运行KitKat的设备,我们仍然需要修复此问题。
nhaarman 2014年

1
对于Jelly Bean(16岁以上),IMMERSIVE_STICKY不起作用。因此,可以显示导航栏(由于,状态栏保持隐藏状态SYSTEM_ALERT)。我们可以使用来检测到这一点OnSystemUiVisibilityChangeListener,然后再次启用这些标志。但是,由于某种原因,此操作只能在大约一秒钟后生效,这足以按下主屏幕按钮。MX Player不使用IMMERSIVE STICKY(工具栏上出现横条),但是横条在您不知道的情况下再次消失。
nhaarman 2014年

1
KitKat的Github Gist:gist.github.com/nhaarman/8291022。Github Gist(果冻豆):gist.github.com/nhaarman/8291070
nhaarman 2014年

7
仅供参考,有些应用程序需要锁定。例如,信息亭类型的应用程序,其中所有者允许临时访问该硬件。我现在正在创建一个照相亭应用程序,我不希望用户(正在拍照的人)除了拍照(还有其他一些事情)之外还能做其他任何事情。所有者可以通过软件按钮解锁,否则需要关闭。抱歉,您在回答开头的“母亲建议”以错误的方式使我(我相信包括OP在内的其他人)受到了挫折。不过,谢谢您的回答,我会调查一下。
ntgCleaner'2

13

我遵循了shaobin0604的回答,并最终通过添加以下内容锁定了HOME按钮:

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

AndroidManifest.xml所有你需要做的就是复制HomeKeyLocker.java杨少斌的lib到项目,并实现它就像在杨少斌的例子。顺便说一句:我的AVD的Android版本是Android 4.0.3


在Android 4.4.4中可以使用吗?因为,它在运行于4.4.4的Moto G中进行了尝试。它对我不起作用。
venkat 2014年

1
该库仅禁用硬主页按钮。MotoG具有软主页按钮,因此它不起作用.. @ venkat
Harry Sharma

警报是一个很好的解决方案,即使不是最好的解决方案,但请记住,在某些设备(例如Nexus 4)上,此方法将不起作用,并且主页按钮仍然可用!
JacksOnF1re 2015年

12

您可以使用Android-HomeKey-Locker禁用HOME KEY和其他系统密钥(例如BACK KEY和MENU KEY)

希望这对您的应用程序有帮助。谢谢。


1
这只是禁用硬主页按钮...!
哈里·夏尔马

为我完美地工作。实际上,我可能想禁用所有物理按钮...因为我的情况很严重,所以使用它来使Google Cardboard禁用“主页”按钮。
马特·克鲁克香克

如何禁用最近使用的应用程序按钮
2013年

#shaobin0604您的github代码无法在Motorola设备上运行。
Brajendra Pandey

11

您可以禁用家庭和最近通话按钮的是Android 5.0,使用固定屏幕功能提到这里

Android 5.0引入了新的屏幕固定API,可让您临时限制用户离开任务或被通知打断。例如,如果您正在开发教育应用程序以支持Android或单一用途或信息亭应用程序上的高风险评估要求,则可以使用此功能。您的应用激活屏幕固定后,用户将无法查看通知,访问其他应用或返回主屏幕,直到您的应用退出该模式。

您可以将设备锁定为信息亭。导航栏不是隐藏的,但是可以根据您激活模式的方式删除或禁用“主页”和“最近”按钮。我测试此功能后,写了一些信息在这里


6

只是一个猜测,但我认为,使用SYSTEM_ALERT_WINDOW权限(显示为“在其他应用上绘制”,请参见此处)是可能的:将您的应用显示为全屏系统警报类型窗口。这样,它将隐藏所有其他应用程序,甚至是主屏幕,因此,如果您按Home,则不会真正禁用它,只是没有任何可见的效果。

MX Player声明了此权限,Facebook Messenger也具有在任何内容上显示“聊天头”的权限-因此,这可能是解决方案。

更新(从我的评论中添加):接下来,将SYSTEM_UI_FLAG_HIDE_NAVIGATION与捕获触摸事件结合使用/使用OnSystemUiVisibilityChangeListener覆盖默认行为(在触摸时出现导航栏)。另外,由于您说退出沉浸式手势不起作用,因此您也可以尝试设置SYSTEM_UI_FLAG_IMMERSIVE_STICKY(使用SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION)。


快速测试(添加权限并调用getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);)显示,这将隐藏状态栏(用于退出沉浸式全屏的向下滑动不起作用),但导航栏则不起作用。该栏上的按钮仍然可以使用。
nhaarman 2014年

我现在没有SDK,但是我的下一个想法是将SYSTEM_UI_FLAG_HIDE_NAVIGATION与捕获触摸事件结合使用/使用OnSystemUiVisibilityChangeListener覆盖默认行为(在触摸时显示导航栏)。
molnarm

另外,由于您说退出沉浸式手势不起作用,因此您也可以尝试设置SYSTEM_UI_FLAG_IMMERSIVE_STICKY(使用SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM_UI_FLAG_HIDE_NAVIGATION)。
molnarm

4

过去可以禁用“主页”按钮,但现在不能。这是由于恶​​意软件会诱骗用户。

您可以在此处查看更多详细信息:在Android 4.0+中禁用“主页”按钮

最后,可以禁用“后退”按钮,如您在另一个问题中看到的:在android中禁用“后退”按钮


2
正如他在Nexus 4上所说的那样,我刚刚测试了MX Player,它确实锁定了主页按钮= S
Pozzo Apps

后退按钮旨在按照其设计的方式工作。我建议不要禁用后退按钮。
Raghunandan

我明白你的意思,@ Raghunandan,并同意这一点。不过,可以禁用“后退”按钮,我相信开发人员可以考虑到这一点。如果他设法破坏了应用程序的可用性,那么他的用户将告知他。
Alvaro Cavalcanti

尝试安装MX Player并进行测试。禁用HOME按钮。它禁用所有系统按钮。MX Player使用儿童锁(插件)。我试图拆卸儿童锁(插件),但尚不知道它如何工作。这就是为什么我问这个问题。
user1024 2013年

1
请注意,这个答案并不能提供这样的MX播放器实现了该功能。
nhaarman 2014年

3

如果您定位的是android 5.0及更高版本。您可以使用:

Activity.startLockTask()

这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方留下评论-您可以随时对自己的帖子发表评论,一旦拥有足够的声誉,您就可以在任何帖子中发表评论。-来自评论
user1140237 '02

1
@ user1140237为什么不呢?
Trilarion '16

1
仅当您是设备管理员时才能执行此操作,而普通应用程序则不应该这样
Ron

3

首先创建一个方法:

public void hideNavigationBar() {
        final View decorView = this.getWindow().getDecorView();
        final int uiOptions =
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                YourActivityName.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        decorView.setSystemUiVisibility(uiOptions);

                    }
                });
            }
        };

        timer.scheduleAtFixedRate(task, 1, 2);

    }

然后在onCreate()活动方法上调用它。在onResume()方法上再次调用它。然后,您可以在活动中添加另一个方法,如下所示:

@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        hideNavigationBar();
    }

就是这样。请记住,它将锁定屏幕直到下一次用户触摸屏幕为止,在Timer类中,您可以更改延迟并且可以更改该实例的内容,然后它将再次锁定屏幕。


2

我也在一段时间内进行了搜索,最后终于能够按需要进行操作,即,即使长按电源按钮,导航栏也无法访问,状态栏也无法访问,即使电源菜单和导航按钮均未显示。感谢@Assaf Gamliel,他的回答将我带到了正确的道路。我对教程进行了一些细微的修改。在指定Type时,我指定的WindowManager.LayoutParams.TYPE_SYSTEM_ERROR不是WindowManager.LayoutParams.TYPE_PHONE,否则我们的“覆盖”将不会隐藏系统栏。您可以使用“标志”,“高度”,“宽度”等,使其表现出所需的效果。


1

我不知道如何禁用主页按钮。只要我的知识我得到以下链接。

参考链接: -http //developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME

按键代码常数:Home键。该密钥由框架处理,并且永远不会交付给应用程序。

但是,我们可以禁用后退按钮。希望以下代码对您有所帮助。

@Override
public void onBackPressed() {
    //return nothing 
    return;
}

2
问题是要专门模仿MX播放器功能。
nhaarman 2014年

1

刷新旧主题。我能够实现在按下主页按钮(物理或虚拟)时我的活动不会折叠。这是我的活动onCreate()方法代码:

super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alarm_screen);
        context = getApplicationContext();
        int windowType;
        if (Build.VERSION.SDK_INT>=26) windowType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        else windowType = WindowManager.LayoutParams.TYPE_TOAST;
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                windowType,
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_FULLSCREEN,
                PixelFormat.TRANSLUCENT
        );
        wm = (WindowManager) getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);

        mTopView = (ViewGroup) getLayoutInflater().inflate(R.layout.activity_alarm_screen, null);
        getWindow().setAttributes(params);
        //Set up your views here
        testView = mTopView.findViewById(R.id.test);
        wm.addView(mTopView, params);

在API 26及更高版本上,您需要获得用户的屏幕覆盖权限。在Android 7和8上测试。


0

您无法从ICS关键字禁用“主页”按钮,但可以按以下方式禁用其他按钮

@Override
public boolean dispatchKeyEvent(KeyEvent keyEvent){
   return true;
}

1
问题是要专门模仿MX播放器功能。
nhaarman 2014年

0

在发布ICS(即Android 4+)之后,出于安全原因,已删除了HomeButton的替代功能,以便在应用程序被发现为恶意软件时允许用户退出。

另外,不让用户离开应用程序并不是一个很好的实践。但是,由于您正在制作锁屏应用程序,因此您可以将活动声明为Launcher,这样,当按下HomeButton时,它将仅重新启动您的应用程序并保留在其中(用户会注意到一点点闪烁在屏幕上)。

您可以通过以下链接:

http://dharmendra4android.blogspot.in/2012/05/override-home-button-in-android.html


问题是要专门模仿MX播放器功能。
nhaarman 2014年

0

坦白说,至少在新的api级别(即从4.0开始)上,无法禁用主页按钮。也不建议这样做。但是,您可以通过覆盖

public void onBackPressed() {
    // do not call super onBackPressed.
}

为了覆盖“主页”按钮,您可以使用一个计时器,例如,每次检查主屏幕是否在屏幕上,或者包是否在顶部时(我确定您会获得链接) ),并使用标志single_top显示您的活动。

这样,即使按下主页按钮,您也可以将应用程序置于顶部。

还要确保该应用程序有退出的方法,因为这类应用程序确实很烦人,永远不要开发。

快乐的编码。

PS:按下主页按钮时,无法拦截主页事件。

您可以使用“附加到窗口”方法以及keyguard方法,但不能用于4.0以后的api级别。


问题是要专门模仿MX播放器功能。
nhaarman 2014年

@NiekHaarman,不是真的。问题是“禁用Home,Back和所有其他系统按钮”。特别是LIKE MX播放器,而不是MIMIC。
亚当

@adam不,我提出触发该答案的问题的赏金是专门模仿MX播放器功能而提出的。
nhaarman 2014年

0

使用旋转会导致异常,因此我使用以下方法修复了我的活动:

HomeKeyLocker locker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_splash);

    locker = new HomeKeyLocker();               
    locker.lock(this);
}

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    locker.unlock();
}

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);
    locker.lock(this);
}

您将需要使用@LêQuang Duy建议。


0

我正在开发一个仅需要为应用锁定平板电脑的应用。首先,我将应用程序设置为MainLauncher,然后使用AndroidView锁定任务栏。最后,我挡住了平板电脑。我并不是要在多个平板电脑型号上使用该功能,因为每种设备型号都有阻止它的功能。

但总的来说,它适用于每个人。您可以使用以下命令

Java.Lang.Runtime.GetRuntime().Exec("su -c sed -i '/VOLUME_UP/s/^# //g' /system/usr/keylayout/Generic.kl");

以禁用按钮为例。但是一切都基于更改系统文件,该文件位于文件夹“ / system / usr / keylayout / ...”内。注意:仅适用于有根设备。

我仍在尝试开发的另一种方法是使用StreamWrite和StreamReader访问RootDirectory并重写整个文件以禁用和启用按钮。

希望这可以帮助。

并且任何问题仍然可用。


0

对于希望完全删除已扎根(或自定义ROM) Android设备上的软导航的任何人,您可以修改build.prop系统文件夹中文本文件。

设置以下变量/值:

gemu.hw.mainkeys=1

这是供应商在具有物理按钮时用来禁用软导航的功能。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.