從上圖可以看出,Sensor是最小的類;Sensor是SensorEvent的成員變量;SensorEventListener是抽象接口,每個APP都有實現,SensorEvent是SensorEventListener的輸入參數;SensorManager是對外接口類,也管理這個Sensor, SensorEvent, SensorEventListener.
1.首先獲得SensorManager: mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
2. 通過SensorManager調用成員函數:getDefaultSensor(參數是Type)
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //default的意思是non-wakeup
3. mSensorManager.registerListener()//採樣率、batch、listener都是通過這個函數賦值的
SensorEventListener
/**
* Used for receiving notifications from the SensorManager when
* there is new sensor data.
*/
public interface SensorEventListener {
/**
* Called when there is a new sensor event. Note that "on changed"
* is somewhat of a misnomer, as this will also be called if we have a
* new reading from a sensor with the exact same sensor values (but a
* newer timestamp).
* @param event the {@link android.hardware.SensorEvent SensorEvent}.
*/
public void onSensorChanged(SensorEvent event);
}
SensorEvent
/**
* This class represents a {@link android.hardware.Sensor Sensor} event and
* holds information such as the sensor's type, the time-stamp, accuracy and of
* course the sensor's {@link SensorEvent#values data}.
*/
public class SensorEvent {
public final float[] values;
/**
* The sensor that generated this event. See
* {@link android.hardware.SensorManager SensorManager} for details.
*/
public Sensor sensor;
/**
* The accuracy of this event. See {@link android.hardware.SensorManager
* SensorManager} for details.
*/
public int accuracy;
/**
* The time in nanosecond at which the event happened
*/
public long timestamp;
}
Sensor
/**
* Class representing a sensor. Use {@link SensorManager#getSensorList} to get
* the list of available sensors.
*/
public final class Sensor {
@Override
public String toString() {
return "{Sensor name=\"" + mName + "\", vendor=\"" + mVendor + "\", version=" + mVersion
+ ", type=" + mType + ", maxRange=" + mMaxRange + ", resolution=" + mResolution
+ ", power=" + mPower + ", minDelay=" + mMinDelay + "}";
}
/* Some of these fields are set only by the native bindings in
* SensorManager.
*/
private String mName;
private String mVendor;
private int mVersion;
private int mHandle;
private int mType;
private float mMaxRange;
private float mResolution;
private float mPower;
private int mMinDelay;
private int mFifoReservedEventCount;
private int mFifoMaxEventCount;
private String mStringType;
private String mRequiredPermission;
private int mMaxDelay;
@UnsupportedAppUsage
private int mFlags;
private int mId;
Sensor() {
}
}
BaseEventQueue是SensorEventQueue的基類,EventQueue用於Clinet和SensorService建立eventconnection用於得到sensor data和enable/disable sensor.
BaseEventQueue
/*
* BaseEventQueue is the communication channel with the sensor service,
* SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
* the queues and the listeners.
*/
private abstract static class BaseEventQueue {
private static native long nativeInitBaseEventQueue(long nativeManager,
WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ,
String packageName, int mode, String opPackageName);
private static native int nativeEnableSensor(long eventQ, int handle, int rateUs,
int maxBatchReportLatencyUs);
private static native int nativeDisableSensor(long eventQ, int handle);
private long mNativeSensorEventQueue;
private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
protected final SystemSensorManager mManager;
BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {
if (packageName == null) packageName = "";
mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
new WeakReference<>(this), looper.getQueue(),
packageName, mode, manager.mContext.getOpPackageName());
mManager = manager;
}
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {//regiseterListener的參數
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0
|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
private int enableSensor(
Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
if (mNativeSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
maxBatchReportLatencyUs);
}
}
SensorEventQueue
static final class SensorEventQueue extends BaseEventQueue {
private final SensorEventListener mListener;
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
public SensorEventQueue(SensorEventListener listener, Looper looper,
SystemSensorManager manager, String packageName) {
super(looper, manager, OPERATING_MODE_NORMAL, packageName);
mListener = listener;
}
@Override
public void addSensorEvent(Sensor sensor) {
SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
mManager.mTargetSdkLevel));
synchronized (mSensorsEvents) {
mSensorsEvents.put(sensor.getHandle(), t);
}
}
// 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);
mListener.onAccuracyChanged(t.sensor, t.accuracy);
}
mListener.onSensorChanged(t); //call into the registerd listener
}
}
SystemSensorManager
nativeCreate獲得sensorservice的接口,進而得到sensor list所有的sensors.
registerLister時client和sensor service建立 eventconnection.