在安卓系统中创建自定义锁屏

16

我正在开发自定义锁屏应用程序。在4.0以下版本中,它可以正常工作,但是在4.0以上版本中,当我们按下主页按钮时,应用程序会停止运行。是否有解决方案可以使应用程序在按下主页按钮之前不停止运行,直至解锁屏幕。(例如go locker 应用程序)


7
抱歉,我无法回答您的问题,但我很好奇您是如何制作自定义锁屏的。我没有找到关于如何制作自定义锁屏的教程,只有制作自定义启动器的教程。您有什么建议吗? - nunoh123
@nunoh123 那么如何开发像Go Locker那样的自定义启动器? - kk1
@nunoh123 这是我设计的锁屏链接:https://dev59.com/oWQn5IYBdhLWcg3wVF7i?rq=1 - kk1
5个回答

14

另一种开发锁屏应用的方式是使用视图(Views),我来解释一下。

首先,在某些设备上,您可以通过禁用KEYGUARD来“禁用”系统锁屏:

((KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE)).newKeyguardLock("IN").disableKeyguard();

你应该将这行代码放在你的 Service 中。

之后,每次屏幕关闭时,你就可以启动一个活动:

public class AutoStart extends BroadcastReceiver {

    public void onReceive(Context arg0, Intent arg1) {
        if(arg1.getAction().equals("android.intent.action.SCREEN_OFF")) {
            Intent localIntent = new Intent(arg0, LockScreen.class);
            localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            localIntent.addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
            arg0.startActivity(localIntent);
        }
    }
}

如果你阅读WindowManager.LayoutParams.TYPE_SYSTEM_ERROR的文档,它解释说这是一种内部系统错误窗口类型,会出现在所有可见的窗口之上。在多用户系统中,仅显示在拥有此窗口的用户的窗口上。

所以现在您可以在所有东西的顶部看到一个活动,但按HOME按钮将退出该活动。

这就是Views的出现之处。您可以从布局资源中填充视图并将其作为TYPE_SYSTEM_ERROR添加到WindowManager中,因此它将位于所有内容的顶部。由于您可以控制何时删除此View,因此最好的位置是在ActivityonDestroy中,因为按HOME按钮只会暂停您的活动,而视图仍然可见。

public WindowManager winManager;
public RelativeLayout wrapperView;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
                        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);
        this.winManager = ((WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE));
        this.wrapperView = new RelativeLayout(getBaseContext());
        getWindow().setAttributes(localLayoutParams);
        View.inflate(this, R.layout.lock_screen, this.wrapperView);
        this.winManager.addView(this.wrapperView, localLayoutParams);
}

 public void onDestroy()
    {
        this.winManager.removeView(this.wrapperView);
        this.wrapperView.removeAllViews();
        super.onDestroy();
    }
为了避免通知栏显示,我添加了标志FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL | FLAG_LAYOUT_IN_SCREEN以消耗所有指针事件。
不要忘记将这两行代码添加到您的清单中:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

从这里开始,您只需要添加锁屏应用程序的逻辑,让用户可以使用他的智能手机 :)


@ErfanMowlaei,我已经在Android 5.1上测试过了,它完美地运行。 - prince
@prince 所以它可以处理 AppSwitch 按钮吗?我的意思是指在 Home 按钮旁边的正方形按钮。 - M. Erfan Mowlaei
2
@prince 嗯,这是个不好的事情,锁屏应该完全阻止该键,以防显示最近使用的应用程序。 - M. Erfan Mowlaei
这项服务用于什么?你是如何将其用于锁屏的? - n3wb
关于SCREEN_OFF的一件事是,它还会以某些方式被触发。一个例子是当你接听电话并将手机靠近耳朵时,屏幕会自动关闭。因此,你的锁屏会被启动。顺便问一下,与"android.intent.action.USER_PRESENT"相比,这个有什么不同呢? - Seph Remotigue
显示剩余5条评论

0
一个自定义启动器基本上就是一个应用程序(你可以让它像网格、列表一样运行,实现自己的拖放等功能),然后你只需要将这些行添加到主活动的意图过滤器中,完成这个步骤后,当你安装你的应用程序并按下主屏幕按钮时,你的应用程序将出现在可用主屏幕列表中。
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />

我找不到的是一种替换锁屏的方法,而像在手机上禁用锁屏并在自定义启动器中使用活动并不能真正替换锁屏^^


0
您可以使用以下方法在Android中禁用Home键:
@Override
public void onAttachedToWindow() {
    this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
    super.onAttachedToWindow();
}

0

我正在使用三星Galaxy S4 5.0进行开发,对我有效的方法是将getWindow().setFlags(..)更改为getWindow().addFlags(..)


0

首先你应该问自己是否真的想劫持主页键。有时你可能需要它。但我认为,在安卓锁屏上放置应用程序,让主页键正常工作,并让底层的安卓锁屏负责设备的密码保护是你实际想要的(除非你想改变默认方式)。

总之,让一个应用程序显示在安卓锁屏上很接近编写自己的自定义锁屏。而且更容易,因为你不必自己管理密码。更不用说它更安全、更可靠,因为你没有劫持主页键。

我就是这样做的,效果非常好。你可以在此处了解详情:

在安卓锁屏上显示网站

这个问题是关于在锁屏上显示网站,因为这就是我感兴趣的,但答案更通用,适用于任何应用程序。你可以在谷歌Play上看到这样的应用程序:

https://play.google.com/store/apps/details?id=com.a50webs.intelnav.worldtime


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接