相关文件目录:/frameworks/base/core/java/android/hardware/SensorManager.java
这个SensorManager主要负责返回传感器类型,从底层获得数据。getSystemService(Stringname)是根据名字返回相应的Manager,这个机制也比较重要,网上有相关资料,在此不展开讨论了;mSensorManager.getDefaultSensor(type)就是获取指定类型的传感器。这些类型在API手册中都能查到,包括温度传感器,重力感应器等。registerListener注册监听器,这是为了能让ManagerSensor回调正确的接口函数,注册的时候我们可以指定sensor的灵敏度,分四个等级,API手册中有相应介绍。
我们来看一下SensorManager的构造函数,它总共干了3件事。
1.获取windowManager实例,监控屏幕旋转状态;
2.调用sensors_module_init()和sensors_module_get_next_sensor()两个JNI方法,初始化sensorList传感器列表;
3.构造SensorThread线程但却没有开启线程,开启是在registerListener里面。
public SensorManager(Looper mainLooper) { mMainLooper = mainLooper; synchronized(sListeners) { if (!sSensorModuleInitialized) { sSensorModuleInitialized = true; nativeClassInit(); //1.获取windowManager实例,并监控屏幕旋转状态 //获取windowManager实例 sWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService("window")); //监控屏幕旋转状态 if (sWindowManager != null) { // if it's null we're running in the system process // which won't get the rotated values try { sRotation = sWindowManager.watchRotation( new IRotationWatcher.Stub() { public void onRotationChanged(int rotation) { SensorManager.this.onRotationChanged(rotation); } } ); } catch (RemoteException e) { } } //2.初始化sensorList传感器列表 //调用了sensors_module_init()JNI方法 sensors_module_init(); final ArrayList<Sensor> fullList = sFullSensorsList; int i = 0; do { Sensor sensor = new Sensor(); //调用了sensors_module_get_next_sensor()JNI方法 i = sensors_module_get_next_sensor(sensor, i); if (i>=0) { //Log.d(TAG, "found sensor: " + sensor.getName() + // ", handle=" + sensor.getHandle()); sensor.setLegacyType(getLegacySensorType(sensor.getType())); fullList.add(sensor); sHandleToSensor.append(sensor.getHandle(), sensor); } } while (i>0); //3.构造SensorThread线程,但是这里并没有开启线程 sSensorThread = new SensorThread(); } } }
registerListener
registerListener里面开启了SensorThread线程,SensorThread是一个死循环,他通过调用native方法sensors_data_poll来轮询下层发来的传感器数据。每次接受到一个数据就会调用代理listener中的onSensorChangedLocked方法,把它封装成一个消息发给自己的messagerHandler,在这里面最终调用注册的onSensorChanged方法,也就是我们上面应用程序接口的中方法。
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { return registerListener(listener, sensor, rate, null); }
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler){ if (listener == null || sensor == null) { return false; } boolean result = true; int delay = -1; switch (rate) { case SENSOR_DELAY_FASTEST: delay = 0; break; case SENSOR_DELAY_GAME: delay = 20000; break; case SENSOR_DELAY_UI: delay = 60000; break; case SENSOR_DELAY_NORMAL: delay = 200000; break; default: delay = rate; break; } synchronized (sListeners) { // look for this listener in our list ListenerDelegate l = null; for (ListenerDelegate i : sListeners) { if (i.getListener() == listener) { l = i; break; } } // if we don't find it, add it to the list if (l == null) { l = new ListenerDelegate(listener, sensor, handler); sListeners.add(l); // if the list is not empty, start our main thread if (!sListeners.isEmpty()) {//如果list不为空,调用sSensorThread.startLocked()开启线程 if (sSensorThread.startLocked()) { if (!enableSensorLocked(sensor, delay)) { // oops. there was an error sListeners.remove(l); result = false; } } else { // there was an error, remove the listener sListeners.remove(l); result = false; } } else { // weird, we couldn't add the listener result = false; } } else { l.addSensor(sensor); if (!enableSensorLocked(sensor, delay)) { // oops. there was an error l.removeSensor(sensor); result = false; } } } return result; }
boolean startLocked(){ try { if (mThread == null) { mSensorsReady = false; SensorThreadRunnable runnable = new SensorThreadRunnable(); Thread thread = new Thread(runnable, SensorThread.class.getName()); thread.start(); synchronized (runnable) { while (mSensorsReady == false) { runnable.wait(); } } mThread = thread; } } catch (InterruptedException e) { } return mThread == null ? false : true; }
线程的run函数用反复调用sensors_data_poll反复调用轮询下层发来的传感器数据,每次接受到一个数据就会调用代理listener中的onSensorChangedLocked方法,把它封装成一个消息发给自己的messagerHandler,在这里面最终调用注册的onSensorChanged方法,也就是我们上面应用程序接口的中方法
public void run() { //Log.d(TAG, "entering main sensor thread"); final float[] values = new float[3]; final int[] status = new int[1]; final long timestamp[] = new long[1]; Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); if (!open()) { return; } synchronized (this) { // we've open the driver, we're ready to open the sensors mSensorsReady = true; this.notify(); } while (true) { // 等待下层发来的传感器数据 final int sensor = sensors_data_poll(sQueue, values, status, timestamp); int accuracy = status[0]; synchronized (sListeners) { if (sensor == -1 || sListeners.isEmpty()) { // we lost the connection to the event stream. this happens // when the last listener is removed or if there is an error if (sensor == -1 && !sListeners.isEmpty()) { // log a warning in case of abnormal termination Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor); } // we have no more listeners or polling failed, terminate the thread sensors_destroy_queue(sQueue); sQueue = 0; mThread = null; break; } final Sensor sensorObject = sHandleToSensor.get(sensor); if (sensorObject != null) { // report the sensor event to all listeners that // care about it. final int size = sListeners.size(); for (int i=0 ; i<size ; i++) { ListenerDelegate listener = sListeners.get(i); if (listener.hasSensor(sensorObject)) { // this is asynchronous (okay to call // with sListeners lock held). //接收到一个数据就会调用onSensorChangedLocked方法 listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy); } } } } } //Log.d(TAG, "exiting main sensor thread"); }
onSensorChangedLocked方法,把接收到的数据封装成一个消息发给自己的messagerHandler。
在Application Framework层中我们需要Libraries层中JNI的支持
我们需要以下几个JNI方法
ensors_module_init
sensors_module_get_next_sensor
sensors_data_poll