Android屏幕相关设置
锁屏设置:
1. 初始值 : <integer name="def_screen_off_timeout">60000</integer>
2. 数据库/data/data/com.android.providers.settings/databases/settings.db中
system 表 screen_off_timeout.
3. 开机锁屏, 在frameworks/policies/base/phone/com/android/internal/policy/impl/KeyguardViewMediator.java 文件中修改 mExternallyEnabled 值为false即可. 或者调用setKeyguardEnabled来解锁.
4. 程序禁止锁屏:
方法一:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
方法二:
mWakeLock = pManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, TAG);
mWakeLock.acquire();
参考:
android禁止锁频 http://my.unix-center.net/~Simon_fu/?p=538
锁屏方法和android事件处理过程分析 http://blog.sina.com.cn/s/blog_3e3fcadd0100hrzf.html
Android下Dialog及Activity屏蔽Home键详解 http://www.linuxidc.com/Linux/2011-10/46150p2.htm
相关参数:
screen_brightness_mode : 锁屏模式,
0 = 手动锁屏
1 = 自动锁屏
private static final int SCREEN_ON_BIT = 0x00000001;
屏幕亮
private static final int SCREEN_BRIGHT_BIT = 0x00000002;
屏幕背光亮
private static final int BUTTON_BRIGHT_BIT = 0x00000004;
按钮背光亮
private static final int KEYBOARD_BRIGHT_BIT = 0x00000008;
键盘背光亮
private static final intBATTERY_LOW_BIT = 0x00000010;
电池电量低
SCREEN_OFF : 全部灭掉
SCREEN_DIM : 只有屏幕暗色
SCREEN_BRIGHT : 屏幕和屏幕背光亮
SCREEN_BUTTON_BRIGHT : 屏幕和按钮亮
ALL_BRIGHT : 全部都亮
设置屏幕超时时间:
PowerManagerService中的 setScreenOffTimeoutsLocked 函数.
屏幕休眠过程:
1.任何输入事件会调用PowerManagerService的 userActivity函数来设置一段时间内电源的状态以及屏幕状态, 改函数会调用 setTimeoutLocked来设置屏幕为SCREEN_BRIGH. setTimeoutLocked会在原来超时值的基础上加上屏幕超时时间(mKeylightDelay), 等待SCREEN_BRIGH超时后判断屏幕暗色时间(mDimDelay)是否大于0, 若是则设置屏幕为SCREEN_DIM. 等SCREEN_DIM超时后设置SCREEN_OFF来关闭整个屏幕亮度.
总的来说屏幕调度过程是:
SCREEN_BRIGH --> SCREEN_DIM --> SCREEN_OFF --> close
mKeylightDelay mDimDelay mScreenOffDelay
当设置POKE_LOCK_SHORT_TIMEOUT标志时: mKeylightDelay = 6s 其他时间为0
当设置POKE_LOCK_MEDIUM_TIMEOUT标志时: mKeylightDelay = 15s 其他时间为0
其他时:
mKeylightDelay = 6s,
mDimDelay = screen_off_timeout - mKeylightDelay - LONG_DIM_TIME(7s);
mScreenOffDelay = LONG_DIM_TIME(7);
也就是说系统全亮持续时间为6s, 大部分都是屏幕和背光亮,暗屏持续时间为7s.
updateLightsLocked : 最终更新亮度配置, 背光亮度控制设备有: lcd, 按钮和键盘!
关闭系统屏保:
mKeyguardManager= (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock= mKeyguardManager.newKeyguardLock("");
mKeyguardLock.disableKeyguard();
KeyguardManager只是负责WindowsManager服务中锁相关的一个接口类.
disableKeyguard需要的权限: DISABLE_KEYGUARD,DevicePolicyManager中密码检查。
==========================================================================
TokenWatcher 辅助类,帮助管理IBinder成员引用计数,主要通过acquire 和 release来绑定和释放IBinder成员, 并且判断从无到有或者从有到无时调用抽象成员acquire 和 release来通知子类事件的发生。 该类继承java.lang.Object类, 可使用wait和notify锁机制。
mKeyguardTokenWatcher 是WindowManagerService.java文件中的一个TokenWatcher子类对象。当禁用锁时调用 mPolicy.enableKeyguard(false), 当使能锁时调用mPolicy.enableKeyguard(true)。 只要有一个IBinder禁止使用锁的话,android的锁屏界面就不会出来。 当锁屏界面在的时候,mKeyguardDisabled=false, 当禁用锁屏界面时mKeyguardDisabled=true.
WindowManagerService的 disableKeyguard和reenableKeyguard方法就是通过mKeyguardTokenWatcher变量控制锁屏和解锁屏的。锁屏还涉及到设备策略管理的状态,接受到设备状态变化的广播(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)时,会锁屏。
PolicyManager 策略管理抽象类,静态函数, 通过"com.android.internal.policy.impl.Policy"类名查找相应的策略类,对于手机来说路径为frameworks/policies/base/phone/com/android/internal/policy/impl/Policy.java 中的类。可以创建 PhoneWindow, PhoneLayoutInflater, PhoneWindowManager三个类对象出来。
在WindowManagerService中的 mPolicy.enableKeyguard实际调用到了 PhoneWindowManager中的enableKeyguard, 继而调用KeyguardViewMediator中的setKeyguardEnabled方法。
输入事件流程:
preprocessEvent
--> mPolicy.preprocessInputEventTq 处理滑盖等事件,返回true则终止往下执行
--> mPolicy.interceptKeyTq 返回动作:睡眠,到用户,到界面,什么都不干。
--> 睡眠 mPowerManager.goToSleep, 受mStayOnConditions变量影响
--> 界面 mPowerManager.userActivity
--> 若屏幕关着,则返回
--> setPowerState 和 setTimeoutLocked(time, SCREEN_BRIGHT)
--> mPolicy.userActivity(取消锁,并等待超时锁)
interceptKeyTq: 判断屏幕是否亮以及锁是否存在执行不同的操作。
如果屏锁着并且亮着,则传递给用户
如果屏锁着但没亮着,不传递给用户并判断是否唤醒屏幕。如果能唤醒的话则准备好锁界面,isWakeKeyWhenKeyguardShowing 这个函数是硬编码排除一些键的唤醒屏幕功能。
若果屏不锁且灭着, 1)电话中并是音量键则不传递用户,直接控制音量
2)若是唤醒键则传递给用户界面(ACTIVITY)
3)默认传递给用户
如果屏不锁且亮, 默认传递给用户
==================================继续往下执行================
如果输入的是挂机和电源键则处理一些通话事件,电源键按下时若屏亮则检测是否为长按事件并且该事件不传递给用户,否则什么都不做。 若果屏亮着按下电源键则进入睡眠状态(ACTION_GO_TO_SLEEP).
如果输入的是一些媒体键并且不是传递给用户的,则发送广播!
处理电话接口的一些事件(接听,振铃静音等)
查询屏幕状态可使用如下方法:
mPowerManager.isScreenOn();
mPowerManager.isScreenBright();
mKeyguardMediator.isShowingAndNotHidden();// 屏幕亮的话用这个方法
mKeyguardMediator.isShowing()); // 屏幕灭的话用这个方法