前面已经学习了Android系统基于MTK6580 平台的kernel,hal,framework 层的机制,接下来可以很容易的写出Psensor的APP了。Psensor 为距离传感器,在实际用途中主要用于拨号时贴脸灭屏,因此,我们只需要实现手靠近手机时候屏幕灭屏,手远离时候屏亮即可。(灭屏的设计主要是基于人脸的误触和手机省电等因素)
Psensor 的应用代码实现如下:
java/xml代码路径:Psensor.java
1. 获得senosr和power服务
//电源服务,获取Power服务用来灭屏操作pm = (PowerManager) getSystemService(Context.POWER_SERVICE);mProximityWakeLock = pm.newWakeLock(32,TAG);//Sensor 服务mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
2. 获取指定的Sensor对象
//获取指定类型的传感器对象mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);lSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
3.创建监听(listener)对象 ---- 程序进入启动时
public class MainActivity extends Activity implements SensorEventListener{protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, " onCreate。。。。"); ....//registerListener注册监听器,这是为了能让ManagerSensor回调正确的接口函数,注册的时候我们可以指定sensor的灵敏度// 参数三,检测的精准度 mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);// SENSOR_DELAY_GAME mSensorManager.registerListener(this, lSensor, SensorManager.SENSOR_DELAY_NORMAL);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {// TODO Auto-generated method stub}//sensor 接收到数据后会回调 该 api@Overridepublic void onSensorChanged(SensorEvent event) {// TODO Auto-generated method stubLog.d(TAG, "onSensorChanged 。。。。"); if (event.sensor == null) { return; } if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) { float distance = event.values[0]; tvX.setText(String.valueOf(distance)); Log.d(TAG,"distance is :"+distance ); if(distance == 0.0){Log.i(TAG, "the psensor is actived!"); if (mProximityWakeLock.isHeld()) {return;} else{//执行灭屏操作mProximityWakeLock.acquire();// 申请设备电源锁} }else{Log.i(TAG, "the psensor is not actived!");if (mProximityWakeLock.isHeld()) {return;} else{mProximityWakeLock.setReferenceCounted(false);//执行亮屏操作mProximityWakeLock.release(); // 释放设备电源锁}}}else if(event.sensor.getType() == Sensor.TYPE_LIGHT){//获取精度 float acc = event.accuracy; //获取光线强度 float lux = event.values[0]; Log.i(TAG, "acc="+acc + " lux="+lux);tvAcc.setText(acc+"");tvLux.setText(lux+"");}}}
备注:这里的监听对象主要是实现接口SensorEventListener,我们可以让主Activity来实现它,调用registerlistener时候this即使listener对象,由于是接口,所以必须实现SensorEventListener里面的抽象方法。另外,由于通常PSensor和LightSensor 在硬件上是一体的,因此,在此我们可以把LightSensor一并实现
4. 注销listener对象 ----- 程序结束时候
@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();Log.i(TAG, "on stop...");if(mSensorManager != null){mProximityWakeLock.release();//释放电源锁,如果不释放finish这个acitivity后仍然会有自动锁屏的效果,不信可以试一试mSensorManager.unregisterListener(this);//注销传感器监听}}
备注:这一步也非常重要,程序结束后,listener 也没有了意义,不然会造成电量消耗,影响续航能力
PS:程序运行具体效果如下,当手遮挡时候,屏幕会灭掉,当使用强光照射时候,lux 的值会变化