Android系统实现距离传感器自动待机功能
在每台新出的Android手机都带有距离传感器(Proximity Sensor),我们也叫接近/靠近传感器,本文将说明在Android2.3系统里实现通过该传感器的数据变化来控制系统自动待机功能。
操作方法
- 01
近期,在调试自己的Android2.3.4系统(s5pv210平台)时,发现硬件上不仅仅有光传感器(Light),还有距离/靠近/接近传感器功能(Proximity),而自己的平台也没有通话功能(一般Proximity Sensor用来做手机通话时听声音时自动关屏功能),故将其利用起来,模仿ipad2做个盖子关屏功能,我这边实现的是靠近让系统待机,相当于我们平台上的短按电源键待机操作。
- 02
对于我们的Proximity Sensor,可以获取到8位精度的值,而我们在Linux驱动上报时只传两个状态:远和近,故在Android HAL上也只传两个状态:0和100cm,这已足够我们功能实现了。
- 03
下面是功能实现的两个步骤:
- 04
1、设置界面开关的实现
- 05
在Settings/Display里添加一项Auto-close screen,这里实现是一个复选框,相应的操作如下:
- 06
1)、修改packages/apps/Settings/res/xml/display_settings.xml文件,添加:
- 07
<CheckBoxPreference android:key="proximity" android:title="@string/proximity_title"/>
- 08
2)、修改packages/apps/Settings/res/values/strings.xml文件,添加:
- 09
<string name="proximity_title">Auto-close screen</string>
- 10
由于此处是实验用,故不实现多国语言,暂不修改其他values-*目录下的strings.xml文件。
- 11
3)、修改packages/apps/Settings/src/com/android/settings/DisplaySettings.java文件,在public class DisplaySettings extends PreferenceActivity implements Preference.OnPreferenceChangeListener类里添加如下内容:
- 12
private static final String KEY_PROXIMITY = "proximity"; private static final String PROXIMITY_CLOSE = "proximity_close"; private CheckBoxPreference mProximity;
- 13
在protected void onCreate(Bundle savedInstanceState)函数里添加如下内容:
- 14
mProximity = (CheckBoxPreference) findPreference(KEY_PROXIMITY); mProximity.setPersistent(false);
- 15
在private void updateState(boolean force)函数里添加如下内容:
- 16
mProximity.setChecked(Settings.System.getInt(getContentResolver(),PROXIMITY_CLOSE,0) != 0);
- 17
在public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)函数里添加如下内容:
- 18
if (preference == mProximity) { Settings.System.putInt(getContentResolver(),PROXIMITY_CLOSE,mProximity.isChecked() ? 1 : 0); }
- 19
至此,整个用户控制界面实现好了,即我们的前台开关控制界面实现好了,接下来要实现后台数据控制了。
- 20
2、后台实际功能实现
- 21
后台相对简单点,因为不用修改太多文件,只需修改frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java文件即可。
- 22
在文件开头相关位置添加如下内容:
- 23
import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.SensorEvent; import android.hardware.Sensor;
- 24
接下来在public class PhoneWindowManager implements WindowManagerPolicy类中添加如下内容:
- 25
static final int DEFAULT_PROXIMITY_SCREEN_CLOSE = 0; int mProximityDefault = DEFAULT_PROXIMITY_SCREEN_CLOSE; private static final String PROXIMITY_CLOSE = "proximity_close"; SensorManager mSensorManager; Sensor mProximitySensor;
- 26
接下来在void observe()函数中添加如下内容:
- 27
resolver.registerContentObserver(Settings.System.getUriFor(PROXIMITY_CLOSE),false,this);
- 28
接下来在上面的函数后添加如下定义内容:
- 29
private SensorEventListener proximityListener = new SensorEventListener(){ @Override public void onSensorChanged(SensorEvent event){ //Log.v(TAG,"onSensorChanged"); switch (event.sensor.getType()){ case Sensor.TYPE_PROXIMITY: if (event.values[0] == 0){//near //Log.v(TAG,"near"); PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); pm.goToSleep(SystemClock.uptimeMillis()); } else {//far //Log.v(TAG,"far"); } break; } //Log.v(TAG,"type="+event.sensor.getType()); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //Log.v(TAG,"onAccuracyChanged"); } }; void updateScreenCloseListerner() { if (mProximityDefault == 1) {//allow proximity sensor to close screen mSensorManager =(SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE); mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); mSensorManager.registerListener(proximityListener,mProximitySensor,SensorManager.SENSOR_DELAY_FASTEST); Log.v(TAG,"proximity control screen allowed"); } else if (mProximityDefault == 0) {//not allow mSensorManager.unregisterListener(proximityListener); Log.v(TAG,"proximity control screen not allowed"); } }
- 30
接下来在public void updateSettings()函数中添加如下内容:
- 31
int proximityDefault = Settings.System.getInt(resolver,PROXIMITY_CLOSE,DEFAULT_PROXIMITY_SCREEN_CLOSE); if (mProximityDefault != proximityDefault) { mProximityDefault = proximityDefault; updateScreenCloseListerner(); }
- 32
至此,整个后台的控制也实现好了,接下来要看你的Proximity Sensor发力了。
- 33
重新编译并烧录Android系统,开机后,我们用手去盖住Proximity Sensor的感应窗口,屏灭了吧。
- 34
我们这样做只能实现自动关屏待机,但也只能利用Proximity Sensor这样做,如果要实现Proximity Sensor远距离自动亮屏,这样可以实现,但一旦Proximity Sensor没有盖住时就一直是亮屏,这样使用不实际。
- 35
实际上,我们要实现自动待机和唤醒,可以使用到Hall Sensor,霍尔传感器,通过磁性变化来控制传感器状态,我们通过获取这状态来控制待机和唤醒,这样的实现在ipad上是实现的了,后期再分享该实现。