屏幕关闭时重新启用键盘锁

时间:2013-12-27 01:28:38

标签: android broadcastreceiver keyguard keyguardlock screen-off

这可能与其他问题类似,但我一直在寻找一段时间,并且找不到适合我特定情况的解决方案。

我的应用程序的BroadcastReceiver目前获取一个完整的唤醒锁,禁用键盘锁,然后启动用户先前选择的另一个活动(另一个应用程序,快捷方式等)。我遇到的问题是当我尝试重新启用键盘锁时(我相信唤醒锁被释放,但我会在另一时间确认它)。

由于调用了另一个活动,我无法使用Window标志,所以我一直在尝试使用KeyguardManager.KeyguardLock来禁用和启用。此外,由于我无法控制用户在其他应用中执行的操作,因此我希望在下次关闭屏幕时重新启用键盘锁。我知道常规的BroadcastReceiver不会起作用,所以我一直在尝试实现一个服务来处理它,这就是我遇到麻烦的地方。

目前,我在第一个BroadcastReceiver被触发时启动服务,我在OnCreate中为服务注册了另一个用于ACTION_SCREEN_OFF的BroadcastReceiver,并让ScreenOffReceiver调用服务的onStartCommand,它应该重新启用keyguard。我在onStartCommand中有一个布尔值来知道哪个BroadcastReceiver称它为。

现在,键盘要么没有重新启用,要么重新启用太快(在屏幕关闭之前)。有什么想法吗?

以下是一些代码:

第一个BroadcastReceiver调用AlarmActivity来打开用户选择的操作:

public class AlarmActivity extends Activity {

public static Boolean keyguardDisabled = false;

PowerManager pm;
WakeLock myWakeLock;

KeyguardManager km;
@SuppressWarnings("deprecation")
KeyguardManager.KeyguardLock keylock;


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

    // code to turn screen on
    // acquire wakelock
    pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    myWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakelock");

    // disable keyguard
    km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    keylock = km.newKeyguardLock("myLock");
    keyguardDisabled = true;

    // start service which will re-enable keyguard on next screen off
    Intent i = new Intent(this, ReenableKeyguardService.class);
            startService(i);

    keylock.disableKeyguard();      
    myWakeLock.acquire();

            // rest of AlarmActivity code

这是服务:

public class ReenableKeyguardService extends Service {
BroadcastReceiver mReceiver = null;

PowerManager pm;
WakeLock myWakeLock;

KeyguardManager km;
@SuppressWarnings("deprecation")
KeyguardManager.KeyguardLock keylock;

@Override
public void onCreate() {
    super.onCreate();
    // REGISTER RECEIVER THAT HANDLES SCREEN OFF LOGIC
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
    mReceiver = new ScreenOffReceiver();
    registerReceiver(mReceiver, filter);
}

@SuppressWarnings("deprecation")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (AlarmActivity.keyguardDisabled == true && ScreenOffReceiver.screenTurnedOff == true) {
        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        myWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakelock");

        km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        keylock = km.newKeyguardLock("myLock");

        keylock.reenableKeyguard();
        keylock = null;

        if (myWakeLock.isHeld()) {
            myWakeLock.release();
            myWakeLock = null;
        }

        AlarmActivity.keyguardDisabled = false;
        ScreenOffReceiver.screenTurnedOff = false;

        stopSelf();
    }
    return 1;
}

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

@Override
public void onDestroy() {

    if(mReceiver!=null) {
        unregisterReceiver(mReceiver);
    }             
}
}

这是ScreenOffReceiver:

public class ScreenOffReceiver extends BroadcastReceiver {

public static Boolean screenTurnedOff = false;

@Override
public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        Intent i = new Intent(context, ReenableKeyguardService.class);
        screenTurnedOff = true;
        context.startService(i);
    }
}
}

1 个答案:

答案 0 :(得分:1)

在重新思考我是如何做到这一点后,我选择处理服务中的所有唤醒锁和密码保护代码,这似乎工作得很好。因此,AlarmActivity只启动服务(我从中删除了所有其他代码),并且ScreenOffReceiver保持不变。以下是更新的服务代码,以防将来帮助任何人:

public class KeyguardService extends Service {
BroadcastReceiver mReceiver = null;
Boolean keyguardDisabled;

PowerManager pm;
WakeLock myWakeLock;

KeyguardManager km;
@SuppressWarnings("deprecation")
KeyguardManager.KeyguardLock keylock;

@SuppressWarnings("deprecation")
@Override
public void onCreate() {
    super.onCreate();

    // code to turn screen on
    // acquire wakelock
    pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    myWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakelock");

    // disable keyguard
    km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    keylock = km.newKeyguardLock("myLock");


    keylock.disableKeyguard();

    // ensure secure keyguard won't be bypassed
    km.exitKeyguardSecurely(null);

    // acquire wakelock that will timeout based on current user setting
    myWakeLock.acquire(Settings.System.getLong(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, 1000));
    keyguardDisabled = true;


    // REGISTER RECEIVER THAT HANDLES SCREEN OFF LOGIC
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
    mReceiver = new ScreenOffReceiver();
    registerReceiver(mReceiver, filter);
}


@SuppressWarnings("deprecation")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (keyguardDisabled == true && ScreenOffReceiver.screenTurnedOff == true) {
        keylock.reenableKeyguard();
        keylock = null;

        if (myWakeLock.isHeld()) {
            myWakeLock.release();
            myWakeLock = null;
        }

        keyguardDisabled = false;
        ScreenOffReceiver.screenTurnedOff = false;

        stopSelf();
    }
    return 1;
}

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

@Override
public void onDestroy() {

    if(mReceiver!=null) {
        unregisterReceiver(mReceiver);
    }             
}
}