Android加速度传感器 -- 抬手亮屏

android系统提供以下传感器供应用层使用,具体如下:

// android.hardware.Sensor
TYPE_ACCELEROMETER 1        // 加速度传感器
TYPE_MAGNETIC_FIELD 2       // 磁力传感器
TYPE_ORIENTATION 3          // 方向传感器
TYPE_GYROSCOPE 4            // 陀螺仪传感器
TYPE_LIGHT 5                // 光线感应传感器
TYPE_PRESSURE 6             // 压力传感器
TYPE_TEMPERATURE 7          // 温度传感器,目前已被TYPE_AMBIENT_TEMPERATURE替代
TYPE_PROXIMITY 8            // 近距离传感器
SENSOR_TYPE_GRAVITY 9       // 重力传感器
TYPE_LINEAR_ACCELERATION 10 // 线性加速度
TYPE_ROTATION_VECTOR 11     // 旋转矢量
TYPE_RELATIVE_HUMIDITY 12   // 湿度传感器
TYPE_AMBIENT_TEMPERATURE 13 // 温度传感器
TYPE_MAGNETIC_FIELD_UNCALIBRATED 14 // 未校准磁力传感器
TYPE_GAME_ROTATION_VECTOR 15
TYPE_GYROSCOPE_UNCALIBRATED 16
... ...
  • 加速度传感器

加速度传感器又称之为G-sensor,返回X、Y、Z三轴的加速度值, 该数值包含地心引力的影响,单位为m/s^2(米每二次方秒)

将手机平放在桌面,x轴默认为0,y轴默认0,z轴默认9.81

将手机朝下放在桌面,z轴为-9.81

将手机向左倾斜,x轴为正值

将手机向右倾斜,x轴为负值

将手机向上倾斜,y轴为正值

将手机向下倾斜,y轴为负值

  • 抬手亮屏

分析抬手动作发现,抬手亮屏需要满足两个条件:

1.手机处于拿起移动状态

2.手机面向人眼处于倾斜状态

并且触发这两个条件的时间间隔约200ms以内

代码很简单,以下是全部代码

public class AwakeActivity extends Activity {

    private static final String TAG = "ansen";
    private SensorManager mSensorManager;
    private PowerManager mPowerManager;
    private Sensor mGravitySensor;
    private PowerManager.WakeLock mWakelock;
    private long shakeTime; // 手机触发拿起动作时间
    private long showTime;
    private float oldY = 0;
    private float subY = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
        mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mWakelock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "smartAwake");

        mSensorManager.registerListener(mSensorEventListener, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL);
//        mWakelock.acquire();

    }

    // 加速度传感器监听
    private SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            smartAwake(event);
        }

        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
        }
    };

    // 抬手亮屏逻辑
    private void smartAwake(SensorEvent event) {
        float[] values = event.values;
        float x = values[0];
        float y = values[1];
        float z = values[2];
        Log.i(TAG, "smartAwake  x= " + x + "  y= " + y + " z=" + z);
        subY = y - oldY;
        if (Math.abs(x) < 3 && y > 0 && z < 9) {
            if(subY > 1){
                shakeTime = System.currentTimeMillis();
                Log.i(TAG, "1");
            }
            oldY = y;
        }

        if (Math.abs(x) < 3 && y > 4 && y < 9 && z > 2 && z < 9) {
            showTime = System.currentTimeMillis();
            Log.i(TAG, "2");
            if (showTime - shakeTime >= 0 && showTime - shakeTime < 200) {
                mWakelock.acquire();
                mWakelock.release();
//                mPowerManager.wakeUp(SystemClock.uptimeMillis(), "smartAwake");
                Log.i(TAG, "smartAwake  Awake");
            }
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mSensorManager.unregisterListener(mSensorEventListener);
    }
}

手机水平放置桌面,三轴值约为:X=0,Y=0,Z=9.8,判断手机是否处于水平状态触发的拿起动作代码为:

(Math.abs(x) < 3 && y > 0 && z < 9)

判断手机处于面向人眼倾斜状态代码如下:

(Math.abs(x) < 3 && y > 4 && y < 9 && z > 2 && z < 9)

其中Math.abs(x) < 3 代表手机X轴处于接近水平状态,Y轴的取值为手机向上倾斜的角度,Z轴同理;这里的(subY > 1)是避免触发1和2两个条件时 手机处于静止状态也能点亮屏幕

屏幕唤醒的代码为:

mPowerManager.wakeUp(SystemClock.uptimeMillis(), "smartAwake");

由于是@hide api,普通应用无法直接调用,因此这里通过mWakelock.acquire(),获取唤醒锁 同样在灭屏情况下能点亮屏幕.

最后记得添加权限:

<uses-permission android:name="android.permission.WAKE_LOCK">uses-permission>

建议手机插上USB的情况下测试 断开USB几分钟后加速度传感器可能会停止工作; 建议在系统环境下 在Service中执行,并且程序注册传感器监听时获取wakelock,再通过PowerManager的wakeUp来唤醒屏幕来实现抬手亮屏

你可能感兴趣的:(Android,#,Basic)