0

这可能看起来与其他问题相似,但我一直在寻找一段时间,并没有找到适用于我的特定情况的解决方案。

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

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

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

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

这是一些代码:

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

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

1 回答 1

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);
    }             
}
}
于 2014-01-03T17:58:14.327 回答