重力传感器(一)——监听数据

(1)前景介绍

在使用Android传感器之前,我们首先要弄清楚当前Android设备支持哪些传感器,只有这样我们才能继续操作。
而一般手机不会集成所有的传感器, 大部分只支持一部分传感器:方向传感器、重力传感器等。

传感器大致可分为三类:

  • 动作(Motion)传感器
  • 环境(Environmental)传感器
  • 位置(Position)传感器

(A)动作传感器:这类传感器在三个轴(X、Y、Z)上测量加速度和旋转角度。

  • 加速(accelerometer)传感器
  • 陀螺仪(gyroscope)传感器
  • 重力(gravity)传感器
  • 线性加速(linear acceleration)传感器
  • 旋转向量(rotational vector)传感器

(B)环境传感器:这类传感器可以测量不同环境的参数,例如周围环境的空气温度和压强、光照强度和湿度。

  • 温度(thermometer)传感器
  • 湿度(humidity)传感器
  • 光线(photometer)传感器
  • 压力(pressure)传感器

(C)位置传感器:这类传感器可以测量设备的物理位置。

  • 方向(orientation)传感器(数据来自加速传感器和磁场传感器)
  • 磁场(magnetic)传感器

以上传感器只是部分,后面将用代码获取到手机所支持的传感器类型。我们顺便了解一下Android SDK提供的Android sensor framework(Android传感器框架),其作用是用来访问当前Android设备内置的传感器,帮助我们完成各种与传感器有关的任务。

TYPE_ACCELEROMETER         //加速度传感器(硬件)
TYPE_MAGNETIC_FIELD        //磁场传感器(硬件)
TYPE_ORIENTATION           //方向传感器(软件传感器,数据来自重力和磁场传感器)
TYPE_GYROSCOPE             //陀螺仪传感器(硬件)
TYPE_LIGHT                 //光线传感器(硬件)
TYPE_PRESSURE              //压力传感器(硬件)
TYPE_PROXIMITY             //临近传感器(硬件)
TYPE_GRAVITY               //重场传感器(硬件或软件)
TYPE_LINEAR_ACCELERATION   //线性加速度传感器(硬件或软件)
TYPE_ROTATION_VECTOR       //旋转矢量传感器(硬件或软件)
TYPE_RELATIVE_HUMIDITY     //湿度传感器(硬件)
TYPE_AMBIENT_TEMPERATURE   //温度传感器(硬件)

(2)Demo

(A)主要类和接口:

  • SensorManager类:用于创建sensor service的实例。该类提供了很多用于访问和枚举传感器、注册和注销传感器监听器的方法(具体实现为SystemSensorManager);
  • Sensor类:提供了一些用于获取传感器技术参数的方法。如版本、类型、生产商等;
  • SensorEvent类:系统使用该类创建传感器事件对象,该对象可以提供与传感器相关的信息;
  • SensorEventListener接口:该接口包含两个回调方法,当传感器的回传值或精度发生变化时,系统会调用这两个回调方法;
    请添加图片描述
    (B)获取系统所有支持的传感器
public class MainActivity extends Activity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);

        SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);  //获取系统的传感器服务并创建实例

        List<Sensor> list = sm.getSensorList(Sensor.TYPE_ALL);  //获取传感器的集合
        for (Sensor sensor:list){
            	tv.append(sensor.getName() + "\n");  //把传感器种类显示在TextView中
        } 
    }
}

(C)获得加速度传感器数据

 public class SensorActivity extends Activity implements SensorEventListener {
     private final SensorManager mSensorManager;
     private final Sensor mAccelerometer;

     public SensorActivity() {
         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
         mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
     }

     protected void onResume() {
         super.onResume();
         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
     }

     protected void onPause() {
         super.onPause();
         mSensorManager.unregisterListener(this);
     }

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

     public void onSensorChanged(SensorEvent event) {
     }
 }

(3)源码解析

(A)

//frameworks/base/core/java/android/hardware/
public interface SensorEventListener {

	public void onSensorChanged(SensorEvent event);

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

(B)

//frameworks/base/core/java/android/hardware/
@SystemService(Context.SENSOR_SERVICE)
public abstract class SensorManager {

	public boolean registerListener(SensorEventListener listener, Sensor sensor,
            int samplingPeriodUs) {
        return registerListener(listener, sensor, samplingPeriodUs, null);
    }

	public boolean registerListener(SensorEventListener listener, Sensor sensor,
            int samplingPeriodUs, Handler handler) {
        int delay = getDelay(samplingPeriodUs);
        return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
    }

	/** @hide */
    protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);

	//...
	
	public void unregisterListener(SensorEventListener listener) {
        if (listener == null) {
            return;
        }

        unregisterListenerImpl(listener, null);
    }

    /** @hide */
    protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor);
}

(C)

//frameworks/base/core/java/android/hardware/
/**
 * Sensor manager implementation that communicates with the built-in
 * system sensors.
 *
 * @hide
 */
public class SystemSensorManager extends SensorManager {

	/**
     * @hide
     */
    @Override
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
                                           int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
    }

	 /**
     * @hide
     */
    @Override
    protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
    }

	// Called from native code.
        @SuppressWarnings("unused")
        @Override
        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
                                           long timestamp) {
            final Sensor sensor = mManager.mHandleToSensor.get(handle);
            if (sensor == null) {
                // sensor disconnected
                return;
            }

            SensorEvent t = null;
            synchronized (mSensorsEvents) {
                t = mSensorsEvents.get(handle);
            }

            if (t == null) {
                // This may happen if the client has unregistered and there are pending events in
                // the queue waiting to be delivered. Ignore.
                return;
            }
            // Copy from the values array.
            System.arraycopy(values, 0, t.values, 0, t.values.length);
            t.timestamp = timestamp;
            t.accuracy = inAccuracy;
            t.sensor = sensor;

            // call onAccuracyChanged() only if the value changes
            final int accuracy = mSensorAccuracies.get(handle);
            if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
                mSensorAccuracies.put(handle, t.accuracy);
                //调用onAccuracyChanged
                mListener.onAccuracyChanged(t.sensor, t.accuracy);
            }
             //调用onSensorChanged
            mListener.onSensorChanged(t);
        }
}

(D)横屏竖用特例

@Override
        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
                                           long timestamp) {
            final Sensor sensor = mManager.mHandleToSensor.get(handle);
            if (sensor == null) {
                // sensor disconnected
                return;
            }
        	
        	//add start
			if(sensor.getType() == Sensor.TYPE_ACCELEROMETER ){
                Log.d("SensorEventQueue","x = " + values[0] + ",y = " + values[1] + ",z = " + values[2]);
                if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                    float tmp;
                    tmp = values[0];
                    values[0] = values[1];
                    values[1] = -tmp;
                }
            }
			//add end
			
		}

以上修改可使OrientationEventListener的竖屏方向返回的orientation=0(原本的orientation=90),从而使App可以拿到正确的Gsensor方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪舞飞影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值