(一)  前言
P-Sensor,距离感应器,可以感应手机和人体距离。具体使用用途是在通话过程中打开P-Sensor,那么当手机屏幕贴近用户脸部时,就会自动感应出手机和人体距离是多少。当小于某一个值时,就会熄灭屏幕,不再接收用户触摸屏幕事件,从而有效的防止通话过程中误触摸事件的出现。(有很多人通话过程中脸部会触碰到挂断键,从而导致通话中断有没有? ^_^)。

(二)  打开P-Sensor
刚才我们讲了,P-Sensor主要用于通话过程中防止用户误操作屏幕,那么我们就以通话过程为例,看看电话程序为P-Sensor做了什么。
a.  电话程序在启动的时候,在PhoneApp.java里面新建了一个P-Sensor的wackLock对象,如下:

复制内容到剪贴板

代码:

mProximityWakeLock =  pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);

其实,wackLock这个东东我们以前讲过,它是用来请求控制屏幕点亮和熄灭的一个东东, 具体可以看这个帖子: http://bbs.51cto.com/thread-1018050-1.html

b.  ok,那既然我们拥有了这个关于P-Sensor对象,怎么使用它呢?
在电话状态发生改变的时候,比如,接通了电话,它就会调用PhoneApp.java的updateProximitySensorMode(Phone.State state)方法,这个方法会根据当前电话的状态,决定要不要打开P-Sensor,
那么如果在通话过程中,电话也就是OFF-HOOK状态,嗯,打开P-Sensor:

复制内容到剪贴板

代码:

if (!mProximityWakeLock.isHeld()) {
                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");
                        mProximityWakeLock.acquire();
                    }

其中mProximityWakeLock.acquire();会辗转调用到PowerManagerService.java的enableProximityLockLocked()方法,顾名思义,这个方法是打开P-Sensor,是的!这个方法会去判断当前手机有没有P-Sensor,如果有的话,就会去向SensorManager注册一个P-Sensor监听器,那么当P-Sensor检测到手机和人体距离发生改变时,就会调用我们PowerManagerService.java的监听器.同样,当电话挂断时,电话模块会去调用mProximityWakeLock.release(flags), 这样就会取消P-Sensor监听器.
ok.. 那么接下来就是分析PowerManagerService里面这个P-Sensor是怎么工作的。

(三)   PowerManagerService里面P-Sensor监听器工作原理
监听器的代码,当P-Sensor检测到距离有变化时发生。

复制内容到剪贴板

代码:

SensorEventListener mProximityListener = new SensorEventListener() {
        public void onSensorChanged(SensorEvent event) {
            long milliseconds = SystemClock.elapsedRealtime();
            synchronized (mLocks) {
                float distance = event.values[0];  //检测到手机和人体的距离
                long timeSinceLastEvent = milliseconds - mLastProximityEventTime;  //这次检测和上次检测的时间差
                mLastProximityEventTime = milliseconds;  //更新上一次检测的时间
                mHandler.removeCallbacks(mProximityTask);
                boolean proximityTaskQueued = false;

// compare against getMaximumRange to support sensors that only return 0 or 1
                boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
                        distance < mProximitySensor.getMaximumRange());  //如果距离小于某一个距离阈值,默认是5.0f,说明手机和脸部距离贴近,应该要熄灭屏幕。

if (mDebugProximitySensor) {
                    Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);
                }
                if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {
                    // enforce delaying atleast PROXIMITY_SENSOR_DELAY before processing
                    mProximityPendingValue = (active ? 1 : 0);
                    mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
                    proximityTaskQueued = true;
                } else {
                    // process the value immediately
                    mProximityPendingValue = -1;
                    proximityChangedLocked(active);   //熄灭屏幕操作
                }

// update mProximityPartialLock state
                boolean held = mProximityPartialLock.isHeld();
                if (!held && proximityTaskQueued) {
                    // hold wakelock until mProximityTask runs
                    mProximityPartialLock.acquire();
                } else if (held && !proximityTaskQueued) {
                    mProximityPartialLock.release();
                }
            }
        }

public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // ignore
        }
    };

代码里面我已经有一些注释,下面来用文字描述下。
a.  首先会拿到这测距离变化的距离,float distance = event.values[0];
b.  检测这次距离变化和上次距离变化时间差,如果小于系统设置的阈值,则不会去熄灭屏幕。过于频繁的操作系统会忽略掉。 所以,如果你感觉P-Sensor不够灵敏,就可以修改这个系统默认值

复制内容到剪贴板

代码:

private static final int PROXIMITY_SENSOR_DELAY = 1000;

如果你改的很小,就会发现P-Sensor会变得灵敏很多。。。
c.  嗯,如果P-Sensor检测到这次距离变化小于系统默认值,且这次是一次正常的变化,那么就应该去熄灭屏幕:

复制内容到剪贴板

代码:

proximityChangedLocked(active);

这里的active是true,同样,在这里它还会判断P-Sensor是否可以用,如果不可用,则返回。。忽略这次距离变化

复制内容到剪贴板

代码:

if (!mProximitySensorEnabled) {
            Slog.d(TAG, "Ignoring proximity change after sensor is disabled");
            return;
        }

如果一切都满足,则调用:

复制内容到剪贴板

代码:

goToSleepLocked(SystemClock.uptimeMillis(),
                        WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);

熄灭屏幕。。

当然了,这里面还有很多,比较复杂,如果大家有兴趣,可以把系统源代码下载下来,慢慢研究啦~

Android距离感应器P-Sensor浅析相关推荐

  1. android距离感应器控制黑屏,白屏

    最近在做一个网络通话的apk,功能和手机打sim卡电话一样.虽然只做java部分,但也遇到很多问题,其中一个就是模拟通话时的状态,要控制屏幕锁屏.我知道是通过手机上的距离感应器来实现,但也搞了好久,今 ...

  2. android距离感应器控制屏幕灭屏白屏

    最近在做一个网络通话的apk,功能和手机打sim卡电话一样.虽然只做java部分,但也遇到很多问题,其中一个就是模拟通话时的状态,要控制屏幕锁屏.我知道是通过手机上的距离感应器来实现,但也搞了好久,今 ...

  3. Android 距离感应器和耳机状态监测(控制Audio输出通道切换)

    * 切换扬声器播放声音 or 听筒播放  * 1. 距离感应器:继承SensorEventListener这个监听,重写onSensorChanged方法  * 2. 检测耳机插入和拔出:Headse ...

  4. android 距离感应器控制屏幕熄灭_书房大变身!有格调的屏幕挂灯,加了它桌面秒变神仙颜值...

    趁着这段时间宅在家里,我把凌乱了好长时间的书房收拾了一下,上网买了一些小清新摆饰,又把一些颜值比较高的音箱.耳机放上去,老婆现在终于不再吼我了. 原先的书房是这样的,真可以用"脏乱差&quo ...

  5. android 距离感应器控制屏幕熄灭_苹果 | 最新折叠专利曝光!屏幕下方无铰链结构解决折痕问题...

    文 | 小C君 · 编译 | Nina.山海观 来源 :Businesspost.Appleinsider CINNO Research 产业资讯,3月10日,IT媒体9to5Mac报道,苹果当天在美 ...

  6. android 距离感应器应用----喇叭、话筒播放音乐

    转自新浪博客sony9997 http://blog.sina.com.cn/s/blog_5462e93f0100w7bn.html AudioManager  audioManager = (Au ...

  7. android Phone 距离感应器锁的实现

    android手机在正常打电话的过程中,靠近面部会灭屏,这个主要是PhoneApp中的mProximityWakeLock的作用.这个锁是在PhoneApp中被初始化的. if ((pm.getSup ...

  8. 距离感应器下的休眠唤醒机制实现

    前言 从事Android framework开发已经两年了,今天起决定把工作上遇到的问题.做过的需求都用博客的形式记录一下,特地新开一个系列---Android framework开发工作记录,有需要 ...

  9. 距离感应器实现锁频教程

    首先说一下android平台下的11种感应器:            1. ACCELEROMETER 加速,描述加速度的.            2.GRAVITY 重力,这个在大家都知道.     ...

最新文章

  1. poj 3740 Easy Finding
  2. 如何扩展Dojo tree成chekbox tree
  3. Windows从命令行创建文本文件的两种方式
  4. 成功解决AttributeError: module tensorflow.sets has no attribute intersection
  5. Redis 之(二) Redis的基本数据结构以及一些常用的操作
  6. 用java做一个模拟彩票程序_JAVA模拟----- 彩票机子-----抽奖过程的实例化
  7. Linux内核:进程上下文切换
  8. python实现用线程爬虫 快速高效爬数据
  9. Python二:【ImageEnhance】+【PIL模块】如何利用python实现图像增强
  10. 推荐一些用CRF做图像语义分割的资源
  11. shell脚本循环执行一个linux命令,Linux中循环执行shell命令的方法
  12. 拓端tecdat|R语言实现绘制Sankey桑基图(河流图、分流图)流程数据可视化
  13. word页眉页脚,奇偶不同
  14. 满足三角不等式的TSP问题的近似算法
  15. 《机器学习算法竞赛实践》学习笔记(1)神经网络
  16. SpringBoot2 综合案例(05):定时任务和JDBC多数据源配置
  17. 流?I/O操作?阻塞?epoll?
  18. 瑞数5维普期刊js逆向
  19. 南京大学计算机技术是重点学科吗,2019南京大学重点学科和重点专业大盘点
  20. 5G+智慧灯杆发展生态峰会闭幕,专家精彩观点汇总

热门文章

  1. 2021中国企业数智服务十大趋势
  2. 国《动画片里的童年》
  3. Tensorflow(二) —— 创建Tensor类型的数据
  4. IT行业2016研究分析
  5. 印度芯片转舵的双重命题
  6. 华硕幻13(ROG flow X13)安装ubuntu20.04驱动问题以及高版本内核无限重启的方法记录
  7. c语言中y=0x20什么意思,ASCII码0x20之前的码分别是什么意义?
  8. Apollo星火计划学习笔记——第八讲Apollo控制模块解析与实践2
  9. ROF系统的主要性能指标及概念和杂谈(佛系更新)
  10. 设置APP字体大小不跟随手机系统字体而改变