5

我构建了一个自定义锁屏应用程序,它使用广播接收器和服务来监听用户何时打开或关闭屏幕并从那里启动我的活动。该活动应该完全取代锁定屏幕。为了做到这一点,我的应用程序应该禁用 android stock lock,以便我的应用程序可以用作新的锁屏。

相反,一旦首次安装应用程序,服务首次启动,应用程序似乎正在工作。当用户重新打开手机时第一次关闭手机屏幕时,他们会看到我的应用程序在顶部运行,并且能够使用我的应用程序解锁他们的手机。但是一旦进入android操作系统,如果用户下次关闭屏幕并重新打开它而不是回到我的应用程序时按下主页按钮,他们就会被带到库存解锁屏幕,我的应用程序在它下面打开,当它应该在顶部时。

这是我的代码:

我的服务:

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {

        super.onCreate();
        Log.d("MyService","Service STARTED");
        final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        final BroadcastReceiver mReceiver = new ScreenReceiver();
        registerReceiver(mReceiver, filter);
    }
}

我的广播接收器:

public class ScreenReceiver extends BroadcastReceiver {

public static ArrayList<String> runningApplications = new ArrayList<String>();
private Context ctext;
public static boolean screenIsLocked;
public static KeyguardManager keyguardManager;
public static KeyguardLock lock;

@Override
public void onReceive(final Context context, final Intent intent) {
    ctext = context;
    keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
    lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
    lock.disableKeyguard();


    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        screenIsLocked = true;
        Log.d("ScreenReceiver", "False");

        Intent intenti = new Intent();
        intenti.setClass(context, starterActivity.class);
        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intenti);


    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        screenIsLocked = false;
        Log.d("ScreenReceiver", "True");

                    Intent intenti = new Intent();
                    intenti.setClass(context, starterActivity.class);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intenti);
    }
}

我开始的活动基本上是空的,只有一个解锁按钮finish();在按下时调用。

4

2 回答 2

4

与键盘保护相关的逻辑的行为可能因设备而异。这是因为锁屏通常由设备制造商定制(即非库存),其中一些尊重您使用的键盘锁逻辑,而另一些则不这样做。

此外,afaik 控制键盘保护的新方法是使用窗口标志:

// inside activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

但这并不能解决问题,设备仍然对此有发言权。

例如,根据我的经验,Galaxy Nexus 会在键盘保护上方显示您的活动窗口,但不会关闭它(您认为 Google 品牌的设备应该尊重该标志,嗯),所以如果您在活动中点击后退按钮 - 您将获得标准锁屏 --- 而 HTC One X 似乎正确处理了解除部分:您的活动窗口将导致标准锁屏按预期解除。

我发现无法强制所有设备正常运行。Android API 并不是为了让您能够创建自定义锁屏(至少目前不是)。看看商店里的那些——它们都有同样的问题,就是不够稳定。

正如 Dianne Hackborn在此 Google Groups 答案中所说,您在这方面可以做的任何事情都是 hack,所以希望它不时打破。

于 2012-07-25T19:31:42.197 回答
2

我试图编译你的代码并得到你所说的同样的错误。我试图对其进行修改以使其正常工作,最终得到了问题!!!

public class ScreenReceiver extends BroadcastReceiver {

    public static ArrayList<String> runningApplications = new ArrayList<String>();
    private Context ctext;
    public static boolean screenIsLocked;
    public static KeyguardManager keyguardManager;
    public static KeyguardLock lock;

    @Override
    public void onReceive(final Context context, final Intent intent) {
        ctext = context;
        keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
        lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
        lock.disableKeyguard();


        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            screenIsLocked = true;
            Log.d("ScreenReceiver", "False");

            Intent intenti = new Intent();
            intenti.setClass(context, starterActivity.class);
            intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intenti);


        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            screenIsLocked = false;
            Log.d("ScreenReceiver", "True");

                        Intent intenti = new Intent();
                        intenti.setClass(context, starterActivity.class);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intenti);
        }
    }

通过对广播接收器类的这种更改,我能够克服这个问题

试试看有没有问题告诉我。

编辑:我认为问题可能出在finish()方法上....Android 在需要内存时会转储应用程序...我认为finish()可能有助于 android 破坏应用程序(这可能是您的问题随机发生的原因)

于 2012-07-21T17:30:04.573 回答