android 获取屏幕亮度怎么获取手机亮屏了多长时间?

然后统计手机亮屏时间? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。1被浏览901分享邀请回答已解决问题
安卓系统的手机自动亮屏?请帮忙
问题类型:系统设置最近新买了一个海信E860手机,安卓2.2的系统,从昨天开始我发现这手机出了个问题:锁住屏幕过了一段时间以后,本来黑着的屏幕会自己在无任何操作的情况下突然亮了,再自动熄灭、再自动亮、再自动灭&&我很头疼,这手机莫非中邪了,在无任何外界操作的情况下竟然自动亮屏&&求解释、求帮助,骗分的黑蛋蛋就别在这瞎白话了,谢谢合作
浏览次数:3891
用手机阿里扫一扫
最满意答案
这问题还真的只能是系统有问题呢&&不然你的设置也不可能有着种功能刷机换系统吧追问&&我这是第一次用智能机,不会刷机啊,你能详细说下怎么刷机吗?&回答&&百度上的刷机教程有图有真相&很好学的&以前我也不会&就是看着百度教程&&自己刷的&&你去找找&有没有你这个机型的刷机教程吧&如果有那就很简单了&赞同0|评论&&&&&&&&&&&&按默认排序|按时间排序&&&其他回答&共6条&&&&&&13:38mufengchen|&二级看看手机是不是有节电保护时间,跟屏幕背景光超时,这两个时间不要冲突了
答案创立者
以企业身份回答&
正在进行的活动
生意经不允许发广告,违者直接删除
复制问题或回答,一经发现,拉黑7天
快速解决你的电商难题
店铺优化排查提升2倍流量
擅长&nbsp 店铺优化
您可能有同感的问题
扫一扫用手机阿里看生意经
问题排行榜
当前问题的答案已经被保护,只有知县(三级)以上的用户可以编辑!写下您的建议,管理员会及时与您联络!
server is ok为了账号安全,请及时绑定邮箱和手机
android 息屏和亮屏管理
android 息屏和亮屏的实现
之前一直用PowerManager,现在谷歌禁掉了一些方法,实现不了了
暂无任何回答
40160人关注
16449人关注
Copyright (C) 2018 imooc.com All Rights Reserved | 京ICP备 号-11来电亮屏流程分析
本文档是针对手机来电时候自主点亮屏幕这一流程的分析,非常自然的就将其分为2个阶段,第一个是来电,第二个是点亮屏幕。
来电的流程:
来电消息是从RIL层接收到的。然后才開始传递上来。
: AT& RING
: RIL_URC_READER:RING
: RIL_URC_READER Enter processLine
use-Rlog/RLOG-RIL: Nw URC:RING
use-Rlog/RLOG-RIL: receiving RING!!!!!!
use-Rlog/RLOG-RIL: receiving first RING!!!!!!
use-Rlog/RLOG-RIL: sending ECPI!!!!!!
同一时候也向RIL.java上报UNSOL_RESPONSE_CALL_STATE_CHANGED消息,RIL.java收到将才标志转换为RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,这告诉我们真正处理代码在哪个分支里,看以下代码:
processUnsolicited (Parcel p) {//主动上报的命令
…省略代码……
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null);
上面这个通知发到GsmCallTracker.java文件里的构造函数中。在这里面就能看到要找的事件(EVENT_CALL_STATE_CHANGE)了:
GsmCallTracker (GSMPhone phone) {
this.phone =
cm = phone.mCM;
cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
在文件BaseCommands.java中有对函数的实现:
public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mCallStateRegistrants.add(r);
当然EVENT_CALL_STATE_CHANGE这个消息的上会有非常多原因。除了来电消息RING,还有挂断消息NOCARRIER、电话状态改变消息CLCC等,RIL都会作为EVENT_CALL_STATE_CHANGE报给GsmCallTracker.java,GsmCalTracker.java收到之后会。在handleMessage()相应分支中进行处理。代码例如以下:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
进入pollCallsWhenSafe()方法中,又见消息。这回是主动查询CLCC,查询一下通话列表,即查询全部的通话详情,在这个分支 EVENT_POLL_CALLS_RESULT里获得查询结果:
protected void pollCallsWhenSafe() {
needsPoll =
if (checkNoOperationsPending()) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
cm.getCurrentCalls(lastRelevantPoll);
处理EVENT_POLL_CALLS_RESULT消息是在GsmCallTracker.java中:
case EVENT_POLL_CALLS_RESULT:
ar = (AsyncResult)msg.
if (msg == lastRelevantPoll) {
if (DBG_POLL) log(
"handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
needsPoll =
lastRelevantPoll =
handlePollCalls((AsyncResult)msg.obj);
进入handlePollCalls()方法中。在这种方法里将揭开CLCC命令返回參数和connections集合里的元素的是什么关系?handlePollCalls()方法中会进行一个for循环操作。底层查的通话列表用DriverCall类表示。FrameWork层则抽象为GsmConnection类。在这里先看一个关于CLCC命令的样例:
CLCC : 1、0、2、0、0
先是CLCC这个command。后面
第一个參数表示 index序号,
每二个如是0表示来电、1表示去电,
第三个是电话状态。
第四个表示是数据业务还是语音业务。
第五个表示是否是视频会议。后面再跟着号码。
CLCC返回的电话列表中,第一个參数就是没路通话的编号,从1開始编号,相同能够看到GsmCallTracker中保存的GsmConnection的集合connections集合对象是一个数组,数组编号是从0開始的,所以我们会看到会有一个dc.index == i+1;的操作。相应关系就是这里建立的。之后会把底层查的DriverCall对象和GsmCallTracker中保存的GsmConnection对象进行比較。如DriverCall对象为空,我们本地保持的GsmConnection对象存在,非常显然,是这路电话挂断了。反之如过DriverCall对象有,GsmConnection对象不存在,则是一个来电:
if (conn == null && dc != null){
if (newRinging != null) {
phone.notifyNewRingingConnection(newRinging);
在phoneBase.java里发出通知
protected void notifyNewRingingConnectionP(Connection cn) {
if (!mIsVoiceCapable)
syncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
再后面的代码就离开Framework层了,这里把来电消息通知给上层应用:
private void registerForNotifications() {
mCM.registerForNewRingingConnection(this,PHONE_NEW_RINGING_CONNECTION, null);
….后面的代码省略
public void registerForNewRingingConnection(
Handler h, int what, Object obj) {
checkCorrectThread(h);
mNewRingingConnectionRegistrants.addUnique(h, what, obj);
PHONE_NEW_RINGING_CONNECTION这个消息发送出去之后,是在CallNotifier.java文件里处理的:
public void handleMessage(Message msg) {
if(handleMessageMTK(msg)) {
switch (msg.what) {
case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
log("RINGING... (new)");
onNewRingingConnection((AsyncResult) msg.obj);
mSilentRingerRequested =
}…省略代码…
以下有对来电铃音连接事件的处理:
* Handles a "new ringing connection" event from the telephony layer.
private void onNewRingingConnection(AsyncResult r) {
Connection c = (Connection) r.
log("onNewRingingConnection(): state = " + mCM.getState() + ", conn = { " + c + " }");
Call ringing = c.getCall();
Phone phone = ringing.getPhone();
if (ignoreAllIncomingCalls(phone)) {//在这里面会有去查询黑名单或则其它操作,从而决定是否自己主动拒接来电
PhoneUtils.hangupRingingCall(ringing);
…省略代码…
Call.State state = c.getState();//手机状态
// State will be either INCOMING or WAITING.
if (VDBG) log("- connection is ringing!
state = " + state);
if (PhoneUtils.isRealIncomingCall(state)) {
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_RINGING);
if (mApplication.getWiredHeadsetManager().isHeadsetPlugged() && isIncomingMuteOrVibrate()) {
playCallWaitingTone();
PhoneUtils.setAudioMode();
mShouldSkipRing =
startIncomingCallQuery(c);
sendEmptyMessageDelayed(DELAY_AUTO_ANSWER, 3000);
if (VDBG) log("- onNewRingingConnection() done.");
在这之后会依据获取当前手机的状态模式推断是否处于摘机状态等。
PhoneConstants.State state = mCM.getState();
推断响铃的模式:
public void setRingerMode(int ringerMode) {…代码省略…}
startIncomingCallQuery(c)//取数据库查找相应的资源,比方用什么铃音就会去里面查找:
private void startIncomingCallQuery(Connection c) {
if (shouldStartQuery) {
setDefaultRingtoneUri(c);//设置默认的铃声
public void applyDeviceVolume(int device) {…代码省略…}//设置设备音量
public Uri getDefaultRingtone(int type) {}//依据传入的type类型设置默认的铃音,1为TYPE_RINGTONE,2为TYPE_NOTIFICATION
public static CallerInfoToken startGetCallerInfo(Context context, Connection c,CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie,RawGatewayInfo info){}//这里面能够看到呼叫方的号码,和当前电话用的什么网络。
startIncomingCallQuery中最后会运行响铃并通知有来电了:
private void ringAndNotifyOfIncomingCall(Connection c) {
mCallModeler.onNewRingingConnection(c);
函数onNewRingingConnection的实现:
Call onNewRingingConnection(Connection conn) {
Log.i(TAG, "onNewRingingConnection");
updateDualTalkCallInfo();
final Call call = getCallFromMap(mCallMap, conn, true);
if (call != null) {
updateCallFromConnection(call, conn, false);
for (int i = 0; i & mListeners.size(); ++i) {
mListeners.get(i).onIncoming(call);
PhoneGlobals.getInstance().updateWakeState();//这里開始更新唤醒状态
更新唤醒状态:
void updateWakeState() {
…省略代码…
requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
public void requestWakeState(WakeState ws) {
synchronized (this) {
if (mWakeState != ws) {
if(is82SMBPlugged()){
ws = WakeState.SLEEP;
switch (ws) {
case PARTIAL:
mPartialWakeLock.acquire();
if (mWakeLock.isHeld()) {
mWakeLock.release();
case FULL:
mWakeLock.acquire();
if (mPartialWakeLock.isHeld()) {
mPartialWakeLock.release();
case SLEEP:
if (mWakeLock.isHeld()) {
mWakeLock.release();
if (mPartialWakeLock.isHeld()) {
mPartialWakeLock.release();
mWakeState =
以上就基本上完毕了来电流程的总结。
亮屏的流程:
点亮屏幕是从唤醒開始的:
首先依据mProximityPositive的值检查屏幕当前是否处于远离状态,假设是远离状态的话才会去点亮,否则是不会去点亮的。
假设处于远离状态须要去推断唤醒锁是否须要更新。假设须要更新那么就会去运行更新操作。
函数wakeUpNoUpdateLocked(eventTime)的作用就是去推断唤醒锁是否须要更新,首先会依据mWakefulness的值去运行相应的操作,假设为WAKEFULNESS_ASLEEP,且mIPOShutdown为false时候。运行例如以下操作:
case WAKEFULNESS_ASLEEP://接收到唤醒消息
if (!mIPOShutdown) {
sendPendingNotificationsLocked();
mNotifier.onWakeUpStarted();//開始唤醒
mSendWakeUpFinishedNotificationWhenReady =
要開始唤醒就须要捕获亮屏堵塞个数。每捕获一次就添加一个。然后更新广播锁,即是运行函数updatePendingBroadcastLocked()。首先也是捕获堵塞块,也是捕获一次就添加一个,然后发送一个MSG_BROADCAST的消息。且这个消息是异步运行的。
接收到MSG_BROADCAST这个消息后会运行sendNextBroadcast()方法。假设powerState的值等于POWER_STATE_AWAKE,那么就发送唤醒广播。否则就发送休眠广播。
if (powerState == POWER_STATE_AWAKE) {
sendWakeUpBroadcast();//发起唤醒广播
sendGoToSleepBroadcast(goToSleepReason);//发送休眠广播
推断用户界面锁是否更新,依据mUserActivityPending的值决定是否发送异步运行的消息MSG_USER_ACTIVITY,从而运行方法sendUserActivity()。
发送的唤醒广播最重要的操作就是运行方法:
ActivityManagerNative.getDefault().wakingUp(),这种方法不是马上就能完毕的。可能会有一定延迟才干完毕。可是当他完毕后,且系统已经准备好就会发出一个唤醒已经结束的广播:
if (ActivityManagerNative.isSystemReady()) {
mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,mWakeUpBroadcastDone, mHandler, 0, null, null);
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
sendNextBroadcast();
这个广播的接收器例如以下:
private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
sendNextBroadcast();
这里的广播从发送到接收到有一定延迟。甚至可能出现有巨大延迟的状况,由于仅仅有系统觉得亮屏结束的时候才会认定广播接收完毕。
当确认须要更新唤醒锁。即是wakeUpNoUpdateLocked(eventTime)的值为true时,就会去运行更新就是运行方法updatePowerStateLocked()。
updatePowerStateLocked(eventTime)这个函数非常重要,他会去更新非常多锁的状态代码例如以下:
private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
final long now = SystemClock.uptimeMillis();
int dirtyPhase2 = 0;
for (;;) {
int dirtyPhase1 = mD
dirtyPhase2 |= dirtyPhase1;
mDirty = 0;
updateWakeLockSummaryLocked(dirtyPhase1);
updateUserActivitySummaryLocked(now, dirtyPhase1);
if (!updateWakefulnessLocked(dirtyPhase1)) {
updateDreamLocked(dirtyPhase2);
updateDisplayPowerStateLocked(dirtyPhase2);
if (mDisplayReady) {
sendPendingNotificationsLocked();
updateSuspendBlockerLocked();
updateWakeLockSummaryLocked(dirtyPhase1):更新唤醒锁主锁,依据wakeLocked中flag值与上PowerManager.WAKE_LOCK_LEVEL_MASK进行匹配,依据各种匹配结果对mWakeLockSummary进行赋值。这里一共同拥有例如以下几种锁:
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK:保持CPU 运转,同意保持屏幕显示但有可能是灰的,同意关闭键盘灯
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转。同意保持屏幕高亮显示。同意关闭键盘灯
FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
我们这里关注的就是FULL_WAKE_LOCK。当mWakefulness不为WAKEFULNESS_ASLEEP
mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT。假设此时mWakefulness还等于WAKEFULNESS_AWAKE那么还要或上WAKE_LOCK_STAY_AWAKE。
updateUserActivitySummaryLocked(now, dirtyPhase1):这个函数作用就依据不同的情况设置mUserActivitySummary的值,而此时就须要注意给其赋值的三个參数,各自是:按键亮:USER_ACTIVITY_BUTTON_BRIGHT。屏幕亮:USER_ACTIVITY_SCREEN_BRIGHT。和屏幕暗:USER_ACTIVITY_SCREEN_DIM。
updateDisplayPowerStateLocked(dirtyPhase2):这个函数的作用是更新显示状态锁的。这里面最重要的newScreenState屏幕状态值,screenBrightness屏幕亮度值。函数中会对按键背光亮灭做处理:
if ( ( (mWakeLockSummary & WAKE_LOCK_BUTTON_BRIGHT) != 0 ) ||
( (mUserActivitySummary & USER_ACTIVITY_BUTTON_BRIGHT) != 0) ) {
mButtonLight.setBrightness(screenBrightness);
mButtonLight.turnOff();
mDisplayReady显示是否准备好,他会通过mDisplayPowerController的requestPowerState方法推断得出,注意这里有延时,或者是说有了反馈消息才干获得mDisplayReady的值。requestPowerState方法返回的是mDisplayReadyLocked。而仅仅有当change的值为false,即是状态锁没有更新的时候。在有更改的时候可能会去发送更新电源状态锁即是运行函数sendUpdatePowerStateLocked(),而这个函数的作用就是发出一个更新电源状态的消息:MSG_UPDATE_POWER_STATE。接收消息的地方是:
switch (msg.what) {
case MSG_UPDATE_POWER_STATE:
updatePowerState();
updatePowerState():更新电源状态,这个函数非常重要,后文重点说明。
updateSuspendBlockerLocked():这个函数主要是对mWakeLockSuspendBlocker和mDisplaySuspendBlocker的获取和释放进行操作。并对相应的锁进行设值,获取设为true。释放设为false。
updateDreamLocked(dirtyPhase2):更新休眠锁,这个函数是对休眠状态下进行一些处理。当中会发出一个MSG_SANDMAN消息,处理这个消息的是handleSandman()方法。
以下重点介绍下updatePowerState()方法:
private void updatePowerState() {
…省略代码…
…依据距离传感器设置亮灭屏和是否激活距离传感器…
…光感功能…
if (wantScreenOn(mPowerRequest.screenState)) {//反馈屏幕状态亮屏
if (mScreenAutoBrightness &= 0 && mLightSensorEnabled && mPowerRequest.useAutoBrightness) {
target = mScreenAutoB
slow = mUsingScreenAutoB
mUsingScreenAutoBrightness =
target = mPowerRequest.screenB
mUsingScreenAutoBrightness =
if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {//灭屏
target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
mScreenBrightnessDimConfig);
if (FeatureOption.MTK_AAL_SUPPORT) {
nativeSetScreenState(SCREEN_STATE_DIM, clampScreenBrightness(target));
} else if (wasDim) {
if (FeatureOption.MTK_AAL_SUPPORT) {
nativeSetScreenState(SCREEN_STATE_ON, clampScreenBrightness(target));
animateScreenBrightness(clampScreenBrightness(target),
slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);//动态决定缓慢改变亮度还是迅速改变
mUsingScreenAutoBrightness =
//动态运行屏幕亮或者屏幕灭
if (!mScreenOffBecauseOfProximity || mPowerRequest.forceWakeUpEnable) {
if (wantScreenOn(mPowerRequest.screenState)) {
if (!mElectronBeamOffAnimator.isStarted()) {
setScreenOn(true); //设置屏亮
mSbScreenOnIsStart =
if (mPowerRequest.blockScreenOn//亮屏处于堵塞状态且电量等级为0,0为灭屏,1为亮屏
&& mPowerState.getElectronBeamLevel() == 0.0f) {
blockScreenOn();//堵塞亮屏
mPowerState.updateElectronBeam();
unblockScreenOn();//开启亮屏
if (USE_ELECTRON_BEAM_ON_ANIMATION) {
条件一直为false,里面代码忽略
} else {//设置亮屏
mPowerState.setElectronBeamLevel(1.0f);
mPowerState.dismissElectronBeam();
mSbScreenOnIsStart =
} else {//灭屏时就会运行这里
if (!mElectronBeamOnAnimator.isStarted()) {
if (!mElectronBeamOffAnimator.isStarted()) {
if (mPowerState.getElectronBeamLevel() == 0.0f || mShutDownFlag_D) {
setScreenOn(false);//设置灭屏
mShutDownFlag_D =
} else if (mPowerState.prepareElectronBeam(
mElectronBeamFadesConfig ?
ElectronBeam.MODE_FADE :
ElectronBeam.MODE_COOL_DOWN)
&& mPowerState.isScreenOn()) {
mElectronBeamOffAnimator.start();
mElectronBeamOffAnimator.end();
if (mustNotify
&& !mScreenOnWasBlocked
&& !mElectronBeamOnAnimator.isStarted()
&& !mElectronBeamOffAnimator.isStarted()
&& mPowerState.waitUntilClean(mCleanListener)) {
synchronized (mLock) {//确定显示是否准备好,亮度是否变化。异步
if (!mPendingRequestChangedLocked) {
mDisplayReadyLocked =
sendOnStateChangedWithWakelock();
setScreenOn(boolean on):设置亮屏的方法:
if (mPowerState.isScreenOn() != on) {//要处于亮屏状态
mPowerState.setScreenOn(on);
mNotifier.onScreenOn();
mNotifier.onScreenOff();
public void setScreenOn(boolean on) {// mPowerState.setScreenOn(on)
if (mScreenOn != on) {
mScreenOn =
mScreenReady =
scheduleScreenUpdate();//使屏幕更新
public void onScreenOn() {
mBatteryStats.noteScreenOn();
} catch (RemoteException ex) {
scheduleScreenUpdate()终于会去实现接口mScreenUpdateRunnable,会依据是否亮屏mScreenOn ,电子束等级mElectronBeamLevel,屏幕亮度值mScreenBrightness这三个參数设置更新后的屏幕亮度。然后会对方法返回值进行推断即是:
mPhotonicModulator .setState(mScreenOn, brightness)的返回值,它返回的是mChangeInProgress的值,假设为true,则觉得屏幕更新准备好,假设为false。则觉得屏幕更新没有准备好。在这函数运行中可能去实现一个接口,而接口mTask的实现是:
private final Runnable mTask = new Runnable() {
public void run() {
//申请变更知道完毕
for (;;) {//强制反复运行,直到有条件跳出来
final boolean onC
final boolean backlightC
synchronized (mLock) {
on = mPendingOn;
onChanged = (on != mActualOn);
backlight = mPendingB
backlightChanged = (backlight != mActualBacklight);
if (!onChanged && !backlightChanged) {
mChangeInProgress =
mActualOn =
mActualBacklight =
if (onChanged && on) {//有变化且是需点亮状态
mDisplayBlanker.unblankAllDisplays();//点亮屏幕
if (mShutDownFlag) {
Thread.sleep(mDelay);
} catch (InterruptedException e) {}
if (backlightChanged) {//期望亮度值mPendingBacklight和真实亮度值mActualBacklight是否相等,相等时backlightChanged为false,否则为true
mBacklight.setBrightness(backlight);//这里会去底层设置点亮屏。非常重要。backlightChanged才会决定亮不亮屏
mDisplayBlanker.setBlNotify();
Handler monitorHandler = MessageMonitorLogger.getMsgLoggerHandler();
if (monitorHandler != null && monitorHandler.hasMessages(MessageMonitorLogger.START_MONITOR_EXECUTION_TIMEOUT_MSG, monitorHandler)) {
monitorHandler.removeMessages(MessageMonitorLogger.START_MONITOR_EXECUTION_TIMEOUT_MSG, monitorHandler);
if (onChanged && !on) {//有变化且是需熄灭状态
mDisplayBlanker.blankAllDisplays();//熄灭屏幕
postScreenUpdateThreadSafe();
public void unblankAllDisplays() {//开启全显示,这里有可能会有延时
synchronized (this) {
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
mDisplayManagerService.unblankAllDisplaysFromPowerManager();
mBlanked =
mHDMI.hdmiPowerEnable(true);
mWfdShouldBypass =
unblankAllDisplaysFromPowerManager():开启显示,终于会依据全显示的状态值来确定设备开不开启锁,代码例如以下:
switch (mAllDisplayBlankStateFromPowerManager) {
case DISPLAY_BLANK_STATE_BLANKED:
device.blankLocked();
case DISPLAY_BLANK_STATE_UNBLANKED:
device.unblankLocked();
wakingUp()是在ActivityManagerNative.getDefault().wakingUp()调用时才运行,而要掉这里应该是监听到了亮屏,监听器: mPolicy.screenTurningOn(mScreenOnListener)。
private final WindowManagerPolicy.ScreenOnListener mScreenOnListener =
new WindowManagerPolicy.ScreenOnListener() {
public void onScreenOn() {
synchronized (mLock) {
if (mScreenOnBlockerAcquired && !mPendingWakeUpBroadcast) {
mScreenOnBlockerAcquired =
mScreenOnBlocker.release();
}//这个非常重要
public void wakingUp() {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.DEVICE_POWER);
synchronized(this) {
mWentToSleep =
updateEventDispatchingLocked();
comeOutOfSleepIfNeededLocked();//从休眠状态退出来
手机在感受到距离由近及远的时候也会去点亮屏幕:
private final SensorEventListener mProximitySensorListener = new SensorEventListener() {//距离传感器监听器
public void onSensorChanged(SensorEvent event) {
if (mProximitySensorEnabled) {
final long time = SystemClock.uptimeMillis();
final float distance = event.values[0];
boolean positive = distance &= 0.0f && distance & mProximityT
handleProximitySensorEvent(time, positive); // positive 的值为false,表示离开。为true,表示靠近。
当mDisplayReady为true时会运行方法sendPendingNotificationsLocked(),这个函数的作用就是发送关于锁结束的提示,不管是亮屏结束还是熄屏结束都会调用这里,实现的地方例如以下:
if (mSendWakeUpFinishedNotificationWhenReady) {//唤醒过程结束
mSendWakeUpFinishedNotificationWhenReady =
mNotifier.onWakeUpFinished();
if (mSendGoToSleepFinishedNotificationWhenReady) {//休眠过程结束
mSendGoToSleepFinishedNotificationWhenReady =
mNotifier.onGoToSleepFinished();
mSendWakeUpFinishedNotificationWhenReady这个值在刚进入唤醒阶段就被置为了true的,所以最重要的还是什么时候mDisplayReady的值为true。
真正运行亮屏的是底层驱动去做的,而通知底层驱动的是函数:
public void setBrightness(int brightness) {// Task中的
//mBacklight.setBrightness(backlight)
setBrightness(brightness, BRIGHTNESS_MODE_USER);
public void setBrightness(int brightness, int brightnessMode) {
synchronized (this) {
int color = brightness & 0x000000
color = 0xff000000 | (color && 16) | (color && 8) |
setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
protected void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);//这个函数就会实现去通知底层驱动更新屏幕亮度
阅读(...) 评论()

我要回帖

更多关于 android 获取屏幕宽高 的文章

 

随机推荐