这可能与其他问题类似,但我一直在寻找一段时间,并且找不到适合我特定情况的解决方案。
我的应用程序的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);
}
}
}
答案 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);
}
}
}