繁体   English   中英

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

[英]How to disable home button in Android like lock screen apps do?

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

   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警告(“弃用”))。

来源 - 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);

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

清单中的简单更改将允许您的应用注册为主屏幕/启动器,这将使您的.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>

本教程中拉出来

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

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

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

这个答案中拉出来

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

无论哪种方式,您的锁定屏幕活动应覆盖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语句中包含它(例如if(password!=storedPassword||isForegroundAppSpotify) ) 。

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

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

希望这可以帮助!

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


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

}

我已经做了很多研究来设计锁屏,最后找到了解决方案。 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的新手,因此我没有足够的声誉,所以我很抱歉无法分享我提到的所有链接。 一旦我获得访问权限,肯定会更新帖子。

简单回答你的问题是你做不到。

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

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

如果你真的想要“处理”主页按钮,你必须将你的应用程序作为主屏幕。 看到这个这个

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM