如何在锁定屏幕应用程序中禁用Android中的主页按钮呢?

时间:2016-04-03 08:45:36

标签: android homescreen android-homebutton screen-lock

我知道很多次都会问这个问题,但我发现没有一个解决方案可行。 我尝试了下面给出的代码......

   protected void onPause() {
   super.onPause();
    Intent intent = new Intent(this,LockActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    }

它的作用是当Android主屏幕启动时它将当前活动再次带到前面,但是当主屏幕启动时,将活动再次带到前面需要将近3-4秒。

我使用了一些锁定屏幕应用程序,当点击主页按钮时甚至不启动主屏幕。我希望实现这样的目标。

我还使用了onUserLeavesHint方法,onKeyDown方法和onKeyDispatch方法,但它们都不适用于我。

请不要回答或评论,因为无法在Android中禁用主页按钮。对于这样的答案或评论,我建议你在PlayStore上浏览一些锁屏应用程序。我还在github上找到了一个有源代码的工作应用程序。它正在我的手机上工作,应用程序使用disableKeyguard但是当我在我的应用程序中执行相同操作时它不起作用(不推荐使用disableKeyguard,但我使用@supress警告("弃用"))。 / p>

6 个答案:

答案 0 :(得分:7)

来源 - https://github.com/shaobin0604/Android-HomeKey-Locker

//Copy this class
public class HomeKeyLocker {
    private OverlayDialog mOverlayDialog;
    public void lock(Activity activity) {
        if (mOverlayDialog == null) {
            mOverlayDialog = new OverlayDialog(activity);
            mOverlayDialog.show();
        }
    }
    public void unlock() {
        if (mOverlayDialog != null) {
            mOverlayDialog.dismiss();
            mOverlayDialog = null;
        }
    }
    private static class OverlayDialog extends AlertDialog {

        public OverlayDialog(Activity activity) {
            super(activity, R.style.OverlayDialog);
            WindowManager.LayoutParams params = getWindow().getAttributes();
            params.type =  WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
            params.dimAmount = 0.0F; // transparent
            params.width = 0;
            params.height = 0;
            params.gravity = Gravity.BOTTOM;
            getWindow().setAttributes(params);
            getWindow().setFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |  WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 0xffffff);
            setOwnerActivity(activity);
            setCancelable(false);
        }

        public final boolean dispatchTouchEvent(MotionEvent motionevent) {
            return true;
        }

        protected final void onCreate(Bundle bundle) {
            super.onCreate(bundle);
            FrameLayout framelayout = new FrameLayout(getContext());
            framelayout.setBackgroundColor(0);
            setContentView(framelayout);
        }
    }
}

//Paste this in your activity
mHomeKeyLocker = new HomeKeyLocker();
mHomeKeyLocker.lock(this);

答案 1 :(得分:3)

提供完美无根锁屏功能的可靠方法是将您的“储物柜”应用创意与启动器应用相结合。

清单中的简单更改将允许您的应用注册为主屏幕/启动器,这将使您的.apk 完全控制主页按钮:

<application
    android:launchMode="singleTask"
    android:clearTaskOnLaunch="true"
    android:stateNotNeeded="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="ch.arnab.simplelauncher.HomeScreen"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:excludeFromRecents="true"
        android:screenOrientation="nosensor">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <!-- These 2 intent-filters identify a launcher: -->
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
</application>

this tutorial

拉出来

然后您将有两个活动,一个用于主屏幕,一个用于锁定屏幕。

您必须检测屏幕何时关闭/开启,以显示您的锁屏活动:

public class MainActivity extends Activity {

    //Create a receiver for screen-on/screen-off
    BroadcastReceiver mybroadcast = new BroadcastReceiver() {   
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                //Show lock-screen
            }
            else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                //Also show lock-screen, to remove flicker/delay when screen on?
            }

        }
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON));
        registerReceiver(mybroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF));
    }
}

this answer

拉出来

仅供参考:由于您的“锁定屏幕”此时仍将被视为启动器的一部分,因此应用程序将能够在您的锁定屏幕上启动,这在以下情况下会很糟糕:用户有权访问通知抽屉点击消息/推文等,但也适用于:能够在不解锁手机的情况下接听来电。

无论哪种方式,您的锁定屏幕活动都应覆盖onPause,检查用户是否“已通过身份验证”,如果不是,则假定用户打开了某些内容并应返回锁定屏幕:

@Override
public void onPause() {
    super.onPause();
    if(password!=storedPassword) {
      //Lockscreen activity shouldn't ever be escaped without the right password!
      //Return to launcher without root!
      Intent homeIntent = new Intent(Intent.ACTION_MAIN);
      homeIntent.addCategory(Intent.CATEGORY_HOME);
      homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      startActivity(homeIntent);
    }
}

为了获得更好的用户体验,您应该为用户提供允许少数应用程序绕过锁屏的选项(例如Spotify),您可以在上面的if语句中包含该选项(例如{{1} })。

至于在主屏幕上加载应用,您可以参考tutorials on Google创建自己的启动器活动。

组合启动器+锁定屏幕是避免root访问的最简单方法。您可能会发现使用root更容易,但您将限制您的客户群。

希望这有帮助!

答案 2 :(得分:3)

我已经做了很多研究来设计锁屏,最后找到了解决方案。 Android禁用该功能以覆盖除后退按钮以外的系统栏。但是有一些工作要做到这一点:

耐心了解并实施屏幕固定,您将获得成功。

您可以创建一个应用程序来控制您想要实现屏幕固定的所有应用程序,或者您可以直接在要固定的同一应用程序中实现屏幕固定。

我将向您展示本文后面的实现:

<强> 1。首先,您的应用应该是设备所有者。

您可以通过多种方式完成此操作,最简单的方法是执行命令:

adb shell dpm set-device-owner [yourPackageName] /。[MyDeviceAdminReceiver]

创建扩展DeviceAdminReceiver的接收器(MyDeviceAdminReceiver)。你这里不需要任何代码。有关设备所有者实施的更多信息,请参阅此链接
http://florent-dupont.blogspot.com/2015/02/10-things-to-know-about-device-owner.html

以这种方式在AndroidManifest.xml文件中注册接收器:

<receiver
       android:name=".MyDeviceAdminReceiver"
       android:label="@string/app_name"
       android:permission="android.permission.BIND_DEVICE_ADMIN">
     <meta-data
       android:name="android.app.device_admin"
       android:resource="@xml/device_admin" />

       <intent-filter>
         <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
       </intent-filter>
  </receiver>

<强> 2。您的onCreate方法应如下所示:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lock_screen);

    ComponentName deviceAdmin = new ComponentName(this, MyDeviceAdminReceiver.class);
    DevicePolicyManager mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);


    if (mDpm.isDeviceOwnerApp(getPackageName())) {
        mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName()});
    }

    if (mDpm.isLockTaskPermitted(this.getPackageName()))
        startLockTask();

3.取消固定屏幕并使导航栏正常运行

在代码中要取消固定的位置调用函数 stopLockTask()。例如,在我的应用程序中,只要我验证用户输入了正确的密码,我就会调用此函数:

 if (userInput.length() == 4) {

                    if (userInput.equals(passcode)) {
                        userInput = "";
                        etxtPasscodeDisplay.setText("");
                        stopLockTask(); // this is what you need
                        unlockHomeButton(); // A method to show home screen when 
                         passcode is correct
                        finishAffinity(); //kill other activities
                    }

锁屏通常需要的额外信息:

<强> 1。如果您的应用是启动后出现的第一件事:

您需要一个服务(StartAtBootService)和一个接收器(BootCompletedReceiver)。

<强> 2。如果您希望自己的应用在屏幕锁定和解锁后显示 (按下电源按钮以锁定和解锁):

创建扩展服务的AEScreenOnOffService和扩展 BroadcastReceiver 的AEScreenOnOffReceiver,以便在屏幕启动时启动您的活动。

有关我在此提及的所有内容的详细信息,请参阅http://www.sureshjoshi.com/mobile/android-kiosk-mode-without-root/
这是一篇很棒的写作,对我帮助很大。特别感谢作者。

我需要至少10个声望才能发布超过两个链接。由于我是stackoverflow的新手,因此我没有足够的声誉,所以我很抱歉无法分享我提到的所有链接。一旦我获得访问权限,肯定会更新帖子。

答案 3 :(得分:2)

您可以使用shaobin0604 library执行此操作。它也会禁用“后退”按钮。您的活动将如下所示:


public class MainActivity extends Activity {

HomeKeyLocker homeKeyLocker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

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

}

答案 4 :(得分:1)

简单回答你的问题是你不能那样做。

大约四年前,我提出了你提到的解决方案 [Link]

onUserLeavesHint,onKeyDown和onKeyDispatch永远不会“禁用”硬件密钥。

如果您真的想要“处理”主页按钮,则必须将您的应用程序设为主屏幕。请参阅thisthis

如果您确实要在不制作主屏幕应用程序的情况下禁用硬件密钥,则应该根据设备进行root操作并从内核模块中删除相应的设备文件。 (请自担风险!)

答案 5 :(得分:-1)

您可以做的是覆盖主键功能,如下所示:

@Override public boolean onKeyDown(int keyCode, KeyEvent event)
{
    if(keyCode == KeyEvent.KEYCODE_HOME)
    {
        //The Code Want to Perform.
    }
});

然后您应该能够阻止用户使用此按钮返回主屏幕。 希望对你有用。

编辑: 覆盖主页按钮的问题是它被考虑 作为谷歌的一个安全漏洞,因此每当有人找到覆盖它的方法时,谷歌就会修补这个“漏洞”。