手机口袋模式功能

一.口袋模式定义

实际上很难判断手机是否处于口袋中,口袋场景太复杂,目前市场上口袋模式没有一个确定的定义,参考其它手机和自己做过产品。

定义:手机是处于竖立状态并且距离传感器是被遮挡。

实现原理:加速度传感器判断手机是否处于竖立状态,距离传感器判断是否被遮挡。

应用场景:1.来电铃声自动调到最大音,拿出口袋恢复之前声音大小。2.口袋模式下自动锁屏或灭屏,拿出口袋自动解锁或亮屏。。。可以根据产品定义功能。


下面代码是来电铃声自动调到最大音功能为例,该功能实在原生incallUi应用上实现,代码实现位置如下。

packages\apps\InCallUI\src\com\android\incallui\ProximitySensor.java

 
  
//变量声明 begin
private static final float CRITICAL_DOWN_ANGLE = - 8.0f ;
private static final float CRITICAL_UP_ANGLE = 8.0f ;
private static final int SPEED_SHRESHOLD = 800 ;
private SensorManager mSensorManager ;
private Sensor mGsensorAccelerometer ;//加速度传感器
private Sensor mGsensorProximity;//距离传感器
private int mReverseDownFlg = - 1 ;
private float lastX ;
private float lastY ;
private float lastZ ;
private static final int UPTATE_INTERVAL_TIME = 70 ;
private static final String POCKET_MODE = "pocket_mode_for_call";
float tMax = 1.0f ;
float tMaxleft = 0.1f ;
private long lastUpdateTime ;
SensorEventListener mySensorListener ;
boolean disInRang = false ;
int previousMuteMode = - 1 ;
boolean mActFlag = false ;
boolean isPocket = false;
float distance = 10; float MAXRANGDISTANCE =1.0f;
int previousRing = 0 ;
boolean isRing = false ;
AudioManager am ;
//变量声明 end
public ProximitySensor ( Context context , AudioModeProvider audioModeProvider ,
AccelerometerListener accelerometerListener ) {
mContext = context ;
mPowerManager = ( PowerManager ) context . getSystemService ( Context . POWER_SERVICE );
if ( mPowerManager . isWakeLockLevelSupported ( PowerManager . PROXIMITY_SCREEN_OFF_WAKE_LOCK )) {
mProximityWakeLock = mPowerManager . newWakeLock (
PowerManager . PROXIMITY_SCREEN_OFF_WAKE_LOCK , TAG );
} else {
Log . w ( TAG , "Device does not support proximity wake lock." );
mProximityWakeLock = null ;
}
mAccelerometerListener = accelerometerListener ;
mAccelerometerListener . setListener ( this );
mDisplayListener = new ProximityDisplayListener (
( DisplayManager ) context . getSystemService ( Context . DISPLAY_SERVICE ));
mDisplayListener . register ();
mAudioModeProvider = audioModeProvider ;
mAudioModeProvider . addListener ( this );
//变量初始化 begin
am = ( AudioManager ) mContext . getSystemService ( Context . AUDIO_SERVICE );
mSensorManager = ( SensorManager ) mContext . getSystemService ( Service . SENSOR_SERVICE );
mGsensorAccelerometer = mSensorManager . getDefaultSensor ( Sensor . TYPE_ACCELEROMETER ); //获取加速度传感器
mSensorManager . registerListener ( mGsensorListener , mGsensorAccelerometer , SensorManager . SENSOR_DELAY_NORMAL ); //注册传感器监听
mGsensorProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);/获取距离感器         mSensorManager.registerListener(mGsensorListener, mGsensorProximity, SensorManager.SENSOR_DELAY_NORMAL);//注册传感器监听
//变量初始化 end
}
//传感器监听
SensorEventListener mGsensorListener = new SensorEventListener () {
@Override
public void onAccuracyChanged ( Sensor sensor , int accuracy ) {
}
@Override
public void onSensorChanged ( SensorEvent event ) {
TelecomManager telecomManager = getTelecommService (); //获取telecom对象
if ( telecomManager != null && telecomManager . isRinging ()) { //判断当前是否响铃
sRing = true ;
} else { //电话状态不再是响铃状态
isRing = false ;
Log . d ( TAG , "telecomManager not ring " );
//响铃停止恢复之前铃声大小
if(mActFlag){
mActFlag = false; am.setRingerMode(previousMuteMode);             am.setStreamVolume(AudioManager.STREAM_RING,previousRing, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
}
return ;
}
if(event.sensor.getType() == Sensor.TYPE_PROXIMITY){//如果是距离传感器         distance = event.values[0]; //获取值         Log.d( TAG, "distance "+distance);         return;         }
long currentUpdateTime = System . currentTimeMillis ();
long timeInterval = currentUpdateTime - lastUpdateTime ;
lastUpdateTime = currentUpdateTime ;
float x = event . values [ SensorManager . DATA_X ];
float y = event . values [ SensorManager . DATA_Y ];
float z = event . values [ SensorManager . DATA_Z ];
float deltaX = x - lastX ;
float deltaY = y - lastY ;
float deltaZ = z - lastZ ;
float absx = Math . abs ( x );
float absy = Math . abs ( y );
float absz = Math . abs ( z );
lastX = x ;
lastY = y ;
lastZ = z ;
double speed = Math . sqrt ( deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ )/ timeInterval * 10000 ;
if ( event . values [ SensorManager . DATA_Z ] >= CRITICAL_UP_ANGLE ){ //屏幕竖直朝上
mReverseDownFlg = 0 ;
} else if ( event . values [ SensorManager . DATA_Z ] <= CRITICAL_DOWN_ANGLE
&& mReverseDownFlg == 0 ){ //屏幕竖直朝下
mReverseDownFlg = 1 ;
}
if ( absx > absy && absx > absz ) {
if ( x > tMax ) {
isPocket = false;
Log . d ( TAG , "turn left" + " isLeftRight = " + isLeftRight ); //手机向左边翻转
} else if ( x < - tMax ){
isPocket = false;
Log . d ( TAG , "turn right" + " isLeftRight = " + isLeftRight ); //手机向右边翻转
}
} else if ( absy > absx && absy > absz ) {
if ( y > tMax ) {
isPocket = true;
Log . d ( TAG , "turn up" + " isLeftRight = " + isLeftRight ); //手机竖直翻转头向上
} else if ( y <- tMax ){
isPocket = true;
Log . d ( TAG , "turn down" + " isLeftRight = " + isLeftRight ); //手机竖直翻转头向下
}
} else if ( absz > absx && absz > absy ) {
if ( z > 0 ) {
isPocket = false;
Log . d ( TAG , "screen up" ); //手机屏幕向上
} else {
isPocket = false;
Log.d(TAG, "onSensorChanged set slince");//手机屏幕向下
}
Log . d ( TAG , "screen down" + " isLeftRight = " + isLeftRight );
}
} else {
Log . d ( TAG , "unknow action" + " isLeftRight = " + isLeftRight );
}
if(distance >= MAXRANGDISTANCE){ disInRang = false; }else{ disInRang = true;//距离传感器被遮挡 } if(Settings.System.getInt(mContext.getContentResolver(),POCKET_MODE, 1) == 1 && isRing){//开关打开并且响铃 if(disInRang && isPocket && !mActFlag){              mActFlag = true;              previousMuteMode = am.getRingerMode();              am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);              previousRing = am.getStreamVolume(AudioManager.STREAM_RING );//获取铃声大小              am.setStreamVolume(AudioManager.STREAM_RING,am.getStreamMaxVolume(AudioManager.STREAM_RING), AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);//设置为最大铃声              Log.d(TAG, "set max ring = "+am.getStreamMaxVolume(AudioManager.STREAM_RING)+" current ring = "+previousRing);
} }else if(!disInRang && mActFlag){ mActFlag = false; am.setRingerMode(previousMuteMode);//恢复之前铃声          am.setStreamVolume(AudioManager.STREAM_RING,previousRing, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);         Log.d(TAG, "set back current dddaf ring = "+previousRing); }else if(mActFlag){ mActFlag = false; am.setRingerMode(previousMuteMode);//恢复之前铃声          am.setStreamVolume(AudioManager.STREAM_RING,previousRing, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);          Log.d(TAG, "set back current thie swatch is close ring = "+previousRing); }
}
};
TelecomManager getTelecommService () {
if ( mContext != null )
return ( TelecomManager ) mContext . getSystemService ( Context . TELECOM_SERVICE );
return null ;
}
public void tearDown () {
mAudioModeProvider . removeListener ( this );
mAccelerometerListener . enable ( false );
mDisplayListener . unregister ();
turnOffProximitySensor ( true );
//取消注册监听加速度传感器
if ( mSensorManager != null ){
mSensorManager . unregisterListener ( mGsensorListener );
mSensorManager = null ;
}
}



你可能感兴趣的:(android,通信)