Android – 唤醒和解锁设备
应用程序描述:应用程序旨在作为特定客户端的安全程序(不公开部署)。 当应用程序在一段时间内没有检测到移动时,如果应用程序在后台或设备处于睡眠状态,则该应用程序应该发出警报,并将其置于前台。
问题:如果设备处于睡眠和locking状态,则需要唤醒并解锁设备。 使用在SO和其他地方发现的各种技术,我们已经能够(部分地)唤醒和解锁设备,但是只有当设备物理插入计算机时,才能正常运行。 如果设备本身已经拔下,我们testing唤醒 – 解锁,什么也没有发生; 该设备似乎仍然睡着了,应用程序似乎什么也没有(没有警报)。
我已经使用这篇文章关于使用PowerManager和KeyguardManager ,和这个职位使用窗口标志。
这里是目前用来唤醒设备的代码:
public void wakeDevice() { PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG"); wakeLock.acquire(); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); runOnUiThread(new Runnable(){ public void run(){ getWindow().addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } }); }
从我看过/使用的其他一些SO问题的评论和post,似乎PowerManager / KeyguardManager代码应该已经做到了。 同样,正如我之前所说的,当设备通过USB连接到开发机器时,它在技术上是可行的,但是在设备分离的时候绝对没有任何东西。
还要注意,这是我们的第一个Android应用程序,所以我们完全意识到我们可能完全不在我们正在做的事情上。 任何build议,欢迎。
所以简而言之,考虑到上面的代码,为什么设备的行为是基于它是否插入,以及如何改变以唤醒和解锁设备? 预先感谢您的帮助!
我解决了这个问题。 当设备通过USB接入时,我们观察到不同行为的原因是设备的CPU不会进入hibernate状态。 我认为这可能是debugging模式设置的结果,或者只是插入计算机时的行为方式,因为CPU睡眠的省电function是无关紧要的。 很显然,当设备没有插上时,CPU会高兴地小睡一下,而我们观察到随机运行的应用程序(它随时会唤醒自己),时间会不一致。 我进一步假设这是因为发生的less数CPU周期是less量分配的,我们的应用程序将在“随机”时间给予很less的周期。
所以我们的解决scheme是当设备进入后台(在onPause
方法中完成)时,获取部分唤醒锁,然后释放onResume
方法中的锁。 这似乎阻止了CPU的睡眠。 我们将继续使用完整的唤醒locking和键盘lockingfunction,以便在需要时唤醒设备。 使用部分唤醒locking似乎可以防止CPU进入hibernate状态,并且在预期的情况下,设备似乎可以正常唤醒。 这里是我们更新的代码,以防万一有人遇到这个问题:
// Called from onCreate protected void createWakeLocks(){ PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); fullWakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "Loneworker - FULL WAKE LOCK"); partialWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Loneworker - PARTIAL WAKE LOCK"); } // Called implicitly when device is about to sleep or application is backgrounded protected void onPause(){ super.onPause(); partialWakeLock.acquire(); } // Called implicitly when device is about to wake up or foregrounded protected void onResume(){ super.onResume(); if(fullWakeLock.isHeld()){ fullWakeLock.release(); } if(partialWakeLock.isHeld()){ partialWakeLock.release(); } } // Called whenever we need to wake up the device public void wakeDevice() { fullWakeLock.acquire(); KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); }