android有关sensor的源码总结.doc_第1页
android有关sensor的源码总结.doc_第2页
android有关sensor的源码总结.doc_第3页
android有关sensor的源码总结.doc_第4页
android有关sensor的源码总结.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

android有关sensor的源码总结 虽然这篇文章写得很差,因为赶时间,所以就匆匆忙忙地写出来自己作一个笔记。但是我想对大家应该有一点帮助。 1、有关sensor在Java应用程序的编程(以注册多个传感器为例,这程序是我临时弄出来的,可能有错)package com.sensors.acc;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.widget.TextView;import android.hardware.SensorManager;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;public class acc extends Activity float x, y, z; SensorManager sensormanager = null; Sensor accSensor = null; Sensor lightSensor = null; Sensor proximitySensor = null; TextView accTextView = null; /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); sensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); accSensor = sensormanager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT); proximitySensor = sensormanager.getDefaultSensor(Sensor.TYPE_PROXIMITY); accTextView = (TextView)findViewById(R.id.textview_name); SensorEventListener lsn = new SensorEventListener() public void onSensorChanged(SensorEvent e) if (e.sensor = accSensor) Log.d(sensor, found acc sensor); x = e.valuesSensorManager.DATA_X; y = e.valuesSensorManager.DATA_Y; z = e.valuesSensorManager.DATA_Z; accTextView.setText(x = + x + , ny = + y + , nz = + z); else if (e.sensor = lightSensor) Log.d(sensor, found light sensor); accTextView.setText(data is + e.values0); else if (e.sensor = proximitySensor) Log.d(sensor, found proximity sensor); accTextView.setText(distance is + e.values0); public void onAccuracyChanged(Sensor s, int accuracy) ; Override protected void onResume() super.onResume(); / register this class as a listener for the orientation and accelerometer sensors sensormanager.registerListener(lsn, accSensor, SensorManager.SENSOR_DELAY_NORMAL); sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL); sensormanager.registerListener(lsn, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);/ sensormanager.unregisterListener(lsn); Override protected void onStop() / unregister listener sensormanager.unregisterListener(lsn, accSensor); sensormanager.unregisterListener(lsn, lightSensor);sensormanager.unregisterListener(lsn, proximitySensor); super.onStop(); 在onCreate()函数中,调用getSystemService(SENSOR_SERVICE)初始化一个SensorManager实例,为什么要用getSystemService函数,而不直接用new SensorManager呢?我们看此函数的实现,在ApplicationContext.java中,if (SENSOR_SERVICE.equals(name) return getSensorManager();然后getSensorManager()的实现 private SensorManager getSensorManager() synchronized (mSync) if (mSensorManager = null) mSensorManager = new SensorManager(mMainThread.getHandler().getLooper(); return mSensorManager;看到没有?初始化SensorManager的时候需要mMainThread.getHandler().getLooper()这个参数,之个应该是用来传递消息用的,在SensorManager类的构造函数中会把此参数传给类成员mMainLooper。如果用new SensorManager()就需要另外获取mainLooper参数传递进去。2、在android中跟sensor有关的一些文件有SensorManager.java,位于frameworksbasecorejavaandroidhardware目录下,SensorService.java,位于frameworksbaseservicesjavacomandroidserver目录下,android_hardware_SensorManager.cpp,位于frameworksbasecorejni目录下,与SensorManager.java相对应,com_android_server_SensorService.cpp,在frameworksbaseservicesjni目录下,与SensorService.java相对应。还有SystemServer.java文件,HardwareLibhardwareIncludeHardware目录下的Sensor.h头文件。另外我们需要根据Sensor.h实现自己的一个源文件,一般取名为sensors_xxx.c或者sensors_xxx.cpp。3、SensorManager类分析有几个函数比较重要,必须清晰理解它们的实现,才能了解整个传感器系统的实现。从而更好地去实现硬件抽象层的实现。几个比较重要的函数有构造函数SensorManager(), registerListener()和unregisterListener(),其中registerListener()和unregisterListener()有多个,标志为 Deprecated的是过时的,就不要看了。(1)构造函数SensorManager(Looper mainLooper)这个函数首先获取得传感器系统服务,并赋给类成员mSensorService, mSensorService = ISensorService.Stub.asInterface( ServiceManager.getService(Context.SENSOR_SERVICE);这里我要说一句,就是关于这个传感器系统服务,很多书上都说用getSystemService()是获得传感器的系统服务,而它返回的是SensorManager类型,所以以为整个系统都是使用同一个SensorManager类的实例,以为我们在任何地方使用的SensorManager实例都是同一个,它们的公共成员是共享的。但是经过这两天的分析,这种说法是错误的。其实每次调用getSystemService()函数时都初始化一个新的SensorManager实例,而这个SensorManager实例会在构造函数里通过取得传感器系统服务SensorService来实现对下层传感器的一些控制。而这个SensorService才是系统的传感器服务,说服务,不如说它只是SensorService类的一个实例罢了。它只在系统初始化时初始化一次。Android中的系统服务机制应该跟传感器的都差不多一个样,都是由不同的Manager调用下层相同的Service。你可以列举其它的Manager。那它是什么时候初始化呢?它是系统初始化在SystemServer进程里创建的,SystemServer是一个管理很多系统服务的进程,我们转到SystemServer.的main函数里,可以看到一直到调用int2()函数,它会创建一个ServerThread,最终调用AdbSettingsObserver类的run()函数,在run()函数里有这么有一句 / Sensor Service is needed by Window Manager, so this goes first Log.i(TAG, Sensor Service); ServiceManager.addService(Context.SENSOR_SERVICE, new SensorService(context);这里就创建SensorService实例了。在创建这个实例时会在SensorService构造函数中调用jni函数 public SensorService(Context context) if (localLOGV) Log.d(TAG, SensorService startup); _sensors_control_init(); 我们看_sensors_control_init();对应的为static jintandroid_init(JNIEnv *env, jclass clazz) sensors_module_t* module; if (hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t*)&module) = 0) if (sensors_control_open(&module-common, &sSensorDevice) = 0) const struct sensor_t* list; int count = module-get_sensors_list(module, &list); return count; return 0;它主要调用了sensor.h中的sensors_control_open()static inline int sensors_control_open(const struct hw_module_t* module, struct sensors_control_device_t* device) return module-methods-open(module, SENSORS_HARDWARE_CONTROL, (struct hw_device_t*)device);之后在系统任何地方使用的都是这个SensorService实例。最后run()函数调用Looper.loop();就进行消息循环等待了,这就是SystemServer进程的消息服务了。这才真正叫做系统服务嘛。我们继续看SensorManager类的构造函数,取得SensorService后, nativeClassInit();这是一个jni函数,SensorManager类调用的jni函数都在com_android_server_SensorService.cpp里,我们看这函数static voidnativeClassInit (JNIEnv *_env, jclass _this) jclass sensorClass = _env-FindClass(android/hardware/Sensor); SensorOffsets& sensorOffsets = gSensorOffsets; sensorO = _env-GetFieldID(sensorClass, mName, Ljava/lang/String;); sensorOffsets.vendor = _env-GetFieldID(sensorClass, mVendor, Ljava/lang/String;); sensorOffsets.version = _env-GetFieldID(sensorClass, mVersion, I); sensorOffsets.handle = _env-GetFieldID(sensorClass, mHandle, I); sensorOffsets.type = _env-GetFieldID(sensorClass, mType, I); sensorOffsets.range = _env-GetFieldID(sensorClass, mMaxRange, F); sensorOffsets.resolution = _env-GetFieldID(sensorClass, mResolution,F); sensorOffsets.power = _env-GetFieldID(sensorClass, mPower, F);这个函数只是获取和设置一些信息吧,我们不关心。接着 sensors_module_init();我们看这函数static jintsensors_module_init(JNIEnv *env, jclass clazz) int err = 0; sensors_module_t const* module; err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t *)&module); if (err = 0) sSensorModule = (sensors_module_t*)module; return err;它获取了sensor的模块信息,并把它赋给sSensorModule全局变量,之后传的modules参数都为这个。接着在构造函数里 final ArrayList fullList = sFullSensorsList; int i = 0; do Sensor sensor = new Sensor(); 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 (i0);这里主要是通过jni函数sensors_module_get_next_sensor(sensor, i);获取传感器列表,并把它加入自己的fullList列表中。我们看sensors_module_get_next_sensor()函数static jintsensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next) if (sSensorModule = NULL) return 0; SensorOffsets& sensorOffsets = gSensorOffsets; const struct sensor_t* list; int count = sSensorModule-get_sensors_list(sSensorModule, &list); if (next = count) return -1; list += next; jstring name = env-NewStringUTF(list-name); jstring vendor = env-NewStringUTF(list-vendor); env-SetObjectField(sensor, sensorO, name); env-SetObjectField(sensor, sensorOffsets.vendor, vendor); env-SetIntField(sensor, sensorOffsets.version, list-version); env-SetIntField(sensor, sensorOffsets.handle, list-handle); env-SetIntField(sensor, sensorOffsets.type, list-type); env-SetFloatField(sensor, sensorOffsets.range, list-maxRange); env-SetFloatField(sensor, sensorOffsets.resolution, list-resolution); env-SetFloatField(sensor, sensorOffsets.power, list-power); next+; return next它主要是调用HAL层的get_sensors_list()函数取得传感器列表信息。接着在sensorManger构造函数最后 sSensorThread = new SensorThread();创建一个SensorThread()线程。但并未运行,但在SensorThread类的构造函数里会执行jni函数 sensors_data_init();我们看此函数static jintsensors_data_init(JNIEnv *env, jclass clazz) if (sSensorModule = NULL) return -1; int err = sensors_data_open(&sSensorModule-common, &sSensorDevice); return err;它调用了HAL层的sensors_data_open函数,而这个函数位于sensor.h中,它调用的是static inline int sensors_data_open(const struct hw_module_t* module, struct sensors_data_device_t* device) return module-methods-open(module, SENSORS_HARDWARE_DATA, (struct hw_device_t*)device);Modules-methods-open函数。而在SensorThread类的析构函数finalize()里会调用 sensors_data_uninit();static jintsensors_data_uninit(JNIEnv *env, jclass clazz) int err = 0; if (sSensorDevice) err = sensors_data_close(sSensorDevice); if (err = 0) sSensorDevice = 0; return err;在sensor.h里static inline int sensors_data_close(struct sensors_data_device_t* device) return device-common.close(&device-common);那什么时候sSensorThread线程会运行呢?我们在下面看registerListener()函数。(2) 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)在这函数中,先验证rate,然后检测注册的listener在不在本类的sListeners列表中。 for (ListenerDelegate i : sListeners) if (i.getListener() = listener) l = i; break; 如果不在就申请一个listener,并把它加入全局列表sListener中,并调用mSensorService的enableSensor()函数使能传感器,这个enableSensor()函数最终会调用HAL层的active函数和set_delay()函数,使用后然后判断sListener列表是否为空,当然,第一次为空时加入一个新的listener就不为空了,此时就执行sSensorThread的startLocked运行sSensorThread线程了 l = new ListenerDelegate(listener, sensor, handler); result = mSensorService.enableSensor(l, name, handle, delay); if (result) sListeners.add(l); sListeners.notify(); if (!sListeners.isEmpty() sSensorThread.startLocked(mSensorService); 另一方面,如果注册的listener在sListeners列表中,则先调用mSensorService的enableSensor()函数使能传感器,然后把注册的传感器加入到已存在的listener中。 result = mSensorService.enableSensor(l, name, handle, delay); if (result) l.addSensor(sensor); 接下来我们看看startLocked函数,它在SensorThread中, void startLocked(ISensorService service) try if (mThread = null) Bundle dataChannel = service.getDataChannel(); mThread = new Thread(new SensorThreadRunnable(dataChannel), SensorThread.class.getName(); mThread.start(); catch (RemoteException e) Log.e(TAG, RemoteException in startLocked: , e); 第一次mThread为null,然后它调用了service.getDataChannel()函数,此函数在SensorService类中,主要调用了jni函数_sensors_control_open(), public Bundle getDataChannel() throws RemoteException / synchronize so we do not require sensor HAL to be thread-safe. synchronized(mListeners) return _sensors_control_open(); SensorService类中调用的jni函数主要都在com_android_server_SensorService.cpp文件 中,我们看一下这个函数static jobjectandroid_open(JNIEnv *env, jclass clazz) native_handle_t* handle = sSensorDevice-open_data_source(sSensorDevice); if (!handle) return NULL; / new Bundle() jobject bundle = env-NewObject( gBundleOffsets.mClass, gBundleOffsets.mConstructor); if (handle-numFds 0) jobjectArray fdArray = env-NewObjectArray(handle-numFds, gParcelFileDescriptorOffsets.mClass, NULL); for (int i = 0; i numFds; i+) / new FileDescriptor() jobject fd = env-NewObject(gFileDescriptorOffsets.mClass, gFileDescriptorOffsets.mConstructor); env-SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle-datai); / new ParcelFileDescriptor() jobject pfd = env-NewObject(gParcelFileDescriptorOffsets.mClass, gParcelFileDescriptorOffsets.mConstructor, fd); env-SetObjectArrayElement(fdArray, i, pfd); / bundle.putParcelableArray(fds, fdArray); env-CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray, env-NewStringUTF(fds), fdArray); if (handle-numInts 0) jintArray intArray = env-NewIntArray(handle-numInts); env-SetIntArrayRegion(intArray, 0, handle-numInts, &handle-datahandle-numInts); / bundle.putIntArray(ints, intArray); env-CallVoidMethod(bundle, gBundleOffsets.mPutIntArray, env-NewStringUTF(ints), intArray); / delete the file handle, but dont close any file descriptors native_handle_delete(handle); return bundle;它主要调用了HAL层的open_data_source()函数。取得一些文件描述符等信息。接下来SensorThread创建一个线程,调用start()就进入SensorThreadRunnable类的run()函数了,所以我们接着去看run()函数,它首先调用open()函数 if (!open() return; 在open()函数中调用了 jni函数sensors_data_open(fds, ints);static jintsensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray) jclass FileDescriptor = env-FindClass(java/io/FileDescriptor); jfieldID fieldOffset = env-GetFieldID(FileDescriptor, descriptor, I); int numFds = (fdArray ? env-GetArrayLength(fdArray) : 0); int numInts = (intArray ? env-GetArrayLength(intArray) : 0); native_handle_t* handle = native_handle_create(numFds, numInts); int offset = 0; for (int i = 0; i GetObjectArrayElement(fdArray, i); if (fdo) handle-dataoffset+ = env-GetIntField(fdo, fieldOffset); else handle-dataoffset+ = -1; if (numInts 0) jint* ints = env-GetIntArrayElements(intArray, 0); for (int i = 0; i dataoffset+ = intsi; env-ReleaseIntArrayElements(intArray, ints, 0); / doesnt take ownership of the native handle return sSensorDevice-data_open(sSensorDevice, handle);这函数最终调用了HAL层的data_open(),之后run()函数就进入一个while循环了。 while (true) / wait for an event final int sensor = sensors_data_poll(values, status, timestamp); int accuracy = status0; synchronized (sListeners) if (sensor = -1 | sListeners.isEmpty() if (sensor = -1) / we lost the connection to the event stream. this happens / when the last listener is removed. Log.d(TAG, _sensors_data_poll() failed, we ba

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论