sensorandroid
『壹』 android sensor怎樣注冊input
一, 驅動層
在驅動層,內核需要增加和修改的部分包括:
1,相應硬體模塊驅動代碼,包括兩個文件,這里是kionix_accel.h, kionix_accel.c,分別將kionix_accel.h放到kernel/common/customer/include/linux/中,將kionix_accel.c放到kernel/customer/drivers/misc/中;
2,編譯目錄(kernel/customer/drivers/misc/)下的Makefie 和KConfig,在KConfig中增加:
config SENSORS_KXTJ2
tristate "KXTJ2 accelerometer sensor driver"
depends on I2C
help
Say yes here to support Kionix's KXTJ2 accelerometer sensor
在MakeFile 下增加:obj-$(CONFIG_SENSORS_KXTJ2) += kionix_accel.o
3, 在平台編譯配置文件中(也就是make menuconfig生成的),增加:CONFIG_SENSORS_KXTJ2=y------->指定編譯到內核中,如果是m則編譯成ko;
4,在平台模塊代碼文件中(kernel/customer/boards/board-m6g17-t069.c),在相應的i2c配置中,增加此模塊:
static struct i2c_board_info __initdata aml_i2c_bus_info_b[] = {
........
#ifdef CONFIG_SENSORS_KXTJ2
{
I2C_BOARD_INFO("kionix_accel", KIONIX_ACCEL_I2C_ADDR),
//.irq = INT_GPIO_1,
.platform_data = (void *) &kionix_accel_pdata,
},
#endif
}
經過以上幾步操作以後,就可以將此模塊驅動編譯到內核中。
G-sensor driver工作的大致流程:系統開機後,內核會先載入i2c匯流排驅動,然後再載入設備驅動,在設備驅動中的init函數中通過調用i2c_add_driver(&kionix_accel_driver)注冊i2c_driver;此函數將driver注冊到i2c_bus_type的匯流排上,此匯流排的匹配規則是利用i2c_client的名稱和i2c_driver中id_table中的名稱作匹配。其中i2c_client是系統自動創建的,board-m6g17-t069.c文件中的結構變數static struct i2c_board_info __initdata aml_i2c_bus_info_b中需要添加G-sensor的設備信息。
當匹配成功時,i2c_driver中的probe()函數開始執行。
mole_init(kionix_accel_init)---->i2c_add_driver(&kionix_accel_driver)----->static struct i2c_driver kionix_accel_driver = {
.driver = {
.name = KIONIX_ACCEL_NAME,
.owner = THIS_MODULE,
},
.probe = kionix_accel_probe,
.remove = __devexit_p(kionix_accel_remove),
.id_table = kionix_accel_id,
};
Probe()函數kionix_accel_probe()主要完成以下功能:
1.從i2c_client結構中得到初始化信息
2.創建G-sensor的工作隊列
2.注冊input_device設備
3.讀取Chip ID
4.設置寄存器,使能G-sensor
5.設置並啟動中斷
當G-sensor上報數據的時候會觸發中斷,然後在中斷處理函數中提交一個報值的任務到隊列中並禁止中斷。
在工作隊列中讀數G-sensor的數據並上報到input子系統中,最後使能中斷。
系統啟動後,驅動會在/sys/class/input/inputX下生成相應的設備文件,裡面name節點包含有相應的模塊名;
shell@
capabilities
device
event4
id
modalias
name
phys
power
properties
subsystem
uevent
uniq
同時會在/dev/input/裡面也會生成inputX的節點,它是用來實際讀取數據的。
驅動在工作的時候,主要分兩部分:數據的採集及上報、設備的控制;
1,數據的採集主要是指通過I2C從硬體設備讀取相關的數據並把數據上報,讀取數據有兩種方式,一種是通過中斷,當有數據時,設備會發出中斷信號給驅動,驅動去採集,另一種就是採用定時器不斷的去定時採集數據;由於sensor也屬於輸入設備(還有TouchScreen,Keyboard,Mouse,Sensor等),所以上報的時候,也要報到linux kernel的輸入子系統裡面,上層通過相應的子系統設備節點讀取數據。
上報數據的過程:static void report_abs(void)
{
short x,y,z,tilt;
if(read_data(&x,&y,&z,&tilt) != 0) {
/* report the absulate sensor data to input device */
input_report_abs(idev, ABS_X, y);
input_report_abs(idev, ABS_Y, x);
input_report_abs(idev, ABS_Z, z);
input_sync(idev);
}
2,設備的控制包括打開、關閉、設置參數和使能等,一般上層會通過ioctl方式來交互
二, HAL層
android的HAL層,相當於它的應用層中的驅動,HAL與內核硬體驅動密切相關,由於硬體模塊的差別性,HAL代碼的編寫也各有差別,特別是關於sensor的HAL代碼基本上都要自己去實現,但基本架構是一樣的。
sensor的HAL結構基本分兩部分,一部分是控制操作,一部分是數據操作;
1,首先在android\hardware\libhardware\include\hardware目錄下,有sensors.h文件,定義了struct sensors_mole_t(sensor模塊對象結構,如get_list), struct sensor_t(具體sensor設備對象結構,如名字,類型), struct sensors_poll_device_t(每個設備操作數據結構,如激活、設置參數、poll等), typedef struct sensors_event_t(sensor的事件結構,如類型、數據), 同時也定義了所有感測器的類型:
/**
* Sensor types
*/
#define SENSOR_TYPE_ACCELEROMETER 1
#define SENSOR_TYPE_MAGNETIC_FIELD 2
#define SENSOR_TYPE_ORIENTATION 3
#define SENSOR_TYPE_GYROSCOPE 4
#define SENSOR_TYPE_LIGHT 5
#define SENSOR_TYPE_PRESSURE 6
#define SENSOR_TYPE_TEMPERATURE 7 // deprecated
#define SENSOR_TYPE_PROXIMITY 8
#define SENSOR_TYPE_GRAVITY 9
#define SENSOR_TYPE_LINEAR_ACCELERATION 10
#define SENSOR_TYPE_ROTATION_VECTOR 11
#define SENSOR_TYPE_RELATIVE_HUMIDITY 12
#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
在android/hardware/amlogic/sendsors/aml_gsensor目錄是特定平台實際HAL的代碼存放的位置,當然也有的平台只會給一個so的文件,不給源碼。
在sensor_aml.cpp中,首先要定義HAL_MODULE_INFO_SYM,這個是每個HAL模塊必須的,
struct sensors_mole_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: SENSORS_HARDWARE_MODULE_ID,
name: "Sensors mole",
author: "Amlogic",
methods: &sensors_mole_methods,
},
get_sensors_list: sensors__get_sensors_list,
};
static int sensors__get_sensors_list(struct sensors_mole_t* mole,
struct sensor_t const** list)
{
*list = sSensorList;
return ARRAY_SIZE(sSensorList);
}
/* The SENSORS Mole */
static const struct sensor_t sSensorList[] = {
{ "BMA250 3-axis Accelerometer",
"Bosch",
1, SENSORS_ACCELERATION_HANDLE,
SENSOR_TYPE_ACCELEROMETER,
4.0f*9.81f,
(4.0f*9.81f)/1024.0f,
0.2f,
0,
{ }
},
#ifdef ENABLE_LIGHT_SENSOR
{ "Light sensor",
"(none)",
1, SENSORS_LIGHT_HANDLE,
SENSOR_TYPE_LIGHT, 5000.0f, 1.0f, 1.0f, 20000,{ } },
#endif
};
可以看出在事先定義當前支持的sensor模塊,android通過mole->get_sensors_list獲取。
獲取mole後,利用open_sensors();得到hw_device_t ==sensors_poll_device_t==sensors_poll_context_t->device mSensor結構對象,這個結構對象在初始化時會創建相應的sensor對象,且它們都是以SensorBase為基礎類,
sensors_poll_context_t::sensors_poll_context_t()
{
mSensors[aml_accel] = new GSensor();
mPollFds[aml_accel].fd = mSensors[aml_accel]->getFd();
mPollFds[aml_accel].events = POLLIN;
mPollFds[aml_accel].revents = 0;
#ifdef ENABLE_LIGHT_SENSOR
mSensors[aml_light] = new LightSensor();
mPollFds[aml_light].fd = mSensors[aml_light]->getFd();
mPollFds[aml_light].events = POLLIN;
mPollFds[aml_light].revents = 0;
#endif
}
通過mSensor對象就可以調用 activate、setDelay、poll進行激活讀取數據處理了。
mSensors[aml_accel] = new GSensor();
在創建GSensor對象時會對/sys/class/input/inputX目錄下的name讀取,通過對比名稱判斷當前sensor到底是在哪個目錄並記錄下path,在後面對設備進行設置,也就是控制部分會用到這個目錄下的結點;
同時由於GSensor 是繼承sensorBase的,所以在構造sendsorBase的時候會找到相應的/dev下的inputX設備open得到設備fd,用於後面讀取數據,也就是數據部分。
HAL層准備好後,最後會編譯成一個庫,這里為sensor.amlogic.so
三, Framework層
對於每一個模塊,framework層是最復雜的,它涉及到java部分和C++部分,且根據功能,又可分為service部分和manager部分,它們之間是通過binder進行通信的。
frameworks/base/libs/gui/ISensorServer.cpp
class ISensorServer : public IInterface
{
public:
DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0;
virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
};
在Android中,和Sensor相關的幾個類是:
SensorManager : 通過它實現系統對Sensor的相關調用。
SensorEvent :對各個Sensor數據的封裝,具體可以參考Android的開發文檔。
SensorEventListener :對Sensor數據的監視,一旦有數據,就會調相應的函數。
Sensor : 對Sensor的封裝。
對於service部分: 它是負責與HAL層建立聯系並處理實際數據的服務。
frameworks/base/services/sensorservice/sensorService.cpp , 它繼承了public BnSensorServer
系統啟動時會執行systemProcess,同時會載入sensorService.java進程,在sensorService.java的構造函數中調用JNI方法_sensor_control_init()。
sensorService.cpp中SensorService::onFirstRef()會被執行,會創建SensorDevice& dev(SensorDevice::getInstance())對象,通過SensorService::threadLoop()里就對各個sensor進行poll並將數據發送到對應的申請connection中connection->sendEvents(buffer, count, scratch);
SensorDevice是一個單一對象類,故SensorDevice::getInstance()會在同一進程中只保留一個對象,SensorDevice::SensorDevice()通過hardware.c中讀取HAL層生成的sensor.amlogic.so庫。
對於manager部分:它是負責給應用程序提供介面的,與sensorserivce通過binder進行交互數據與控制。
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
frameworks/base/libs/gui/sensorManager.cpp
android_hardware_SensorManager.cpp:
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_mole_init","()I", (void*)sensors_mole_init },
{"sensors_mole_get_next_sensor","(Landroid/hardware/Sensor;I)I", (void*)sensors_mole_get_next_sensor },
{"sensors_create_queue", "()I", (void*)sensors_create_queue },
{"sensors_destroy_queue", "(I)V", (void*)sensors_destroy_queue },
{"sensors_enable_sensor", "(ILjava/lang/String;II)Z", (void*)sensors_enable_sensor },
{"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll },
};
sensors_mole_init()---->SensorManager::getInstance();由於SensorManager也是單一對象類,這里生成實體對象;
sensors_create_queue()----->SensorManager& mgr.createEventQueue():
sp<SensorEventQueue> SensorManager::createEventQueue()
{
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection();
if (connection == NULL) {
// SensorService just died.
LOGE("createEventQueue: connection is NULL. SensorService died.");
continue;
}
queue = new SensorEventQueue(connection);
break;
}
return queue;
}
通過創建一個connection來建立queuece,其實就是利用connection中與sensorService建立的channel:
mSensorChannel = mSensorEventConnection->getSensorChannel();
通過循環獲取sensor list中的各個對象的屬性:
sensors_mole_get_next_sensor()------>sensorManager::getSensorList()----->SensorManager::assertStateLocked()---->mSensorServer->getSensorList()通過binder從sensorService獲取sensorlist;
使能某一sensor對象:
sensors_enable_sensor()---->queue->enableSensor(sensor, delay)---->mSensorEventConnection->setEventRate(handle, us2ns(us))-----> 通過ISensorEventConnection對象與sensorService:SensorEventConnection進行交互-------->SensorService::SensorEventConnection::enableDisable(int handle, bool enabled)---> SensorService::enable()---->mActiveConnections.add(connection)只是將connection加入到激活數組中,而並非直接使能或關閉硬體;
循環監聽事件:
sensorChannel用一對pipe來sensorService到sensorEventQueue的事件信息。
sensors_data_poll()------->queue->read(&event, 1)---->mSensorChannel->read()----->通過pipe<------ SensorChannel::write()<---------mChannel->write() <----------SensorService::SensorEventConnection::sendEvents() <-------activeConnections[i]->sendEvents(buffer, count, scratch)<---------SensorService::threadLoop()
四, 應用層
『貳』 android如何實現陀螺儀 sensor 在 android 嗎
千鋒扣丁學堂Android開發為您解答:
sensors.h中還定義了其他各種sensor。要實現的就是這兩個:
#define SENSOR_TYPE_MAGNETIC_FIELD 2
#define SENSOR_TYPE_ORIENTATION 3
在/hardware/sensors/sensors.cpp 中添加對MAGNETIC_FIELD和ORIENTATION 的支持
[cpp] view plain
//加入需要的宏定義
#define ID_BASE SENSORS_HANDLE_BASE
#define ID_ACCELERATION (ID_BASE+0)
#define ID_MAGNETIC_FIELD (ID_BASE+1)
#define ID_ORIENTATION (ID_BASE+2)
#define S_HANDLE_ACCELEROMETER (1<<ID_ACCELERATION)
#define S_HANDLE_MAGNETIC_FIELD (1<<ID_MAGNETIC_FIELD)
#define S_HANDLE_ORIENTATION (1<<ID_ORIENTATION)
#define SENSORS_NUM 4
#define SUPPORTED_SENSORS ((1<<NUM_SENSORS)-1)
//在 sensor_t sensors_list[] 中添加兩個sensor的信息,
//這些只是一些Sensor的信息,應用程序可以獲取到。
#ifdef MAGNETIC_FIELD
{
name : "XXX 3-axis Magnetic field sensor",
vendor : "XXX company",
version : 1,
handle : S_HANDLE_MAGNETIC_FIELD,
type : SENSOR_TYPE_MAGNETIC_FIELD,
maxRange : 600.0f,//最大范圍
resolution : 30.0f,//最小解析度
power : 6.7f,//這個不太懂
},
#endif
#ifdef ORIENTATION
{
name: "XXX Orientation sensor",
vendor: "XXX company",
version: 1,
handle: S_HANDLE_ORIENTATION,
type: SENSOR_TYPE_ORIENTATION,
maxRange: 360,
resolution: 0.1,
power: 20,
},
#endif
//定義一個結構來保存orientation的信息
static struct orientation{
float azimuth;
float pitch;
float roll;
}orientation;
//在 control__open_data_source()函數中打開設備
static native_handle_t*
control__open_data_source(struct sensors_control_device_t *dev)
{
SensorControl* ctl = (void*)dev;
native_handle_t* handle;
int fd_m = open (MAGNETIC_DATA_DEVICE, O_RDONLY);
LOGD ("Open Magnetic Data source: %d, %d/n", fd_m, errno);
if (fd_m>= 0)
{
dev->fd[ID_MAGNETIC_FIELD] = p(fd_m);
}
return handle;
}
//實現數據的打開和關閉函數
static int
data__data_open(struct sensors_data_device_t *dev, native_handle_t* handle)
{
struct sensors_data_context_t *dev;
dev = (struct sensors_data_context_t *)device;
for(int i=0 ;i<SENSORS_NUM; i++)
{
dev->fd[i] = p(handle->data[i]);
}
native_handle_close(handle);
native_handle_delete(handle);
return 0;
}
static int
data__data_close(struct sensors_data_device_t *dev)
{
struct sensors_data_context_t *dev;
dev = (struct sensors_data_context_t *)device;
for(int i=0 ;i<SENSORS_NUM; i++)
{
if (dev->fd[i] >= 0)
{
close(dev->fd[i]);
}
dev->fd[i] = -1;
}
return 0;
}
//最關鍵的poll函數
static int
data__poll(struct sensors_data_device_t *dev, sensors_data_t* values)
{
SensorData* data = (void*)dev;
int fd = data->events_fd;
//判斷設備是否打開
if(dev->fd[ID_MAGNETIC_FIELD] < 0)
{
LOGD("In %s dev[%d] is not open!/n",__FUNCTION__ ,ID_MAGNETIC_FIELD);
return -1;
}
pollfd pfd[SENSORS_NUM] =
{
//省略其他sensor代碼
{
fd: dev->fd[ID_MAGNETIC_FIELD],
events: POLLIN,
revents: 0
},
//省略其他sensor代碼
};
int err = poll (pfd, SENSORS_NUM, s_timeout);
unsigned int mask = SUPPORTED_SENSORS;
static unsigned int poll_flag=0;
if(poll_flag==0)
{
poll_flag = mask;
}
//省略其他sensor
if(poll_flag&(1<<ID_MAGNETIC_FIELD))
{
if((pfd[ID_MAGNETIC_FIELD].revents&POLLIN) == POLLIN)
{
char rawData[6];
err = read (dev->fd[ID_MAGNETIC_FIELD], &rawData, sizeof(rawData));
if(err<0)
{
LOGE("read magnetic field ret:%d errno:%d/n", err, errno);
return err;
}
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
data->time = timespec_to_ns(&t);
data->sensor = SENSOR_TYPE_MAGNETIC_FIELD;
data->magnetic.status = SENSOR_STATUS_ACCURACY_HIGH;
//上報的數據單位要轉換成 uTesla
data->magnetic.x = ( (rawData[1] << 8 ) | rawData[0])/ MAGNETIC_CONVERT;
data->magnetic.y = ( (rawData[3] << 8 ) | rawData[2])/ MAGNETIC_CONVERT;
data->magnetic.z = ( (rawData[5] << 8 ) | rawData[4])/ MAGNETIC_CONVERT;
//把陀螺儀需要的數據計算出來,用atan2(),頭文件要加上#include <math.h>
float azimuth = atan2( (float)(data->magnetic.x ),(float)(data->magnetic.y) );
if(azimuth<0)
{
azimuth = 360 - fabs(azimuth*180/PI);
}
else
{
azimuth = azimuth*180/PI;
}
orientation.azimuth = 360-azimuth;
//rotation around the X axis.+180~-180 degree
orientation.pitch = atan2( (float)(data->magnetic.y ),(float)(data->magnetic.z)
)*180/PI;
//rotation around the Y axis +90~-90 degree
float roll = atan2( (float)(data->magnetic.x ),(float)(data->magnetic.z) )
*180/PI;
if (roll > 90)
{
roll = -(180.0-roll);
}
else if (roll < -90)
{
roll = 180 + roll;
}
orientation.roll = roll;
}
return S_HANDLE_MAGNETIC_FIELD;
}
if(poll_flag&(1<<ID_MAGNETIC_FIELD))
{
//數據已經計算好了直接上報就行
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
data->time = timespec_to_ns(&t);
data->sensor = SENSOR_TYPE_ORIENTATION;
data->orientation.azimuth = orientation.azimuth;
data->orientation.pitch = orientation.pitch;
data->orientation.roll = orientation.roll;
poll_flag &= ~(1<<ID_ORIENTATION);
return S_HANDLE_ORIENTATION;
}
}
『叄』 android sensor信息能不能hook
首先我們可以用Xposed框架來hook計數感測器的隊列函數dispatchSensorEvent(),這個函數在android.hardware.SystemSensorManager$SensorEventQueue這個類中。隨後在微信運動每次詢問行走步數的時候,我們先獲取當前步數,然後在目前的步數的基礎上加1000步,然後將信息返回給微信運動。微信運動就會誤以為我們運動了1000步,從而達到了欺騙的效果。
關鍵代碼如下:
首先hook android.hardware.SystemSensorManager$SensorEventQueue這個類的dispatchSensorEvent()函數:
final Class<?> sensorEL = findClass("android.hardware.SystemSensorManager$SensorEventQueue",lpparam.classLoader);
XposedBridge.hookAllMethods(sensorEL, "dispatchSensorEvent", new XC_MethodHook()
接著我們在記步感測器把步數信息返回給微信運動之前,將返回的步數加上1000步:
protected void beforeHookedMethod(MethodHookParam param) throws
Throwable {
XposedBridge.log(" mzheng Hooked method: " + param.method);
((float[]) param.args[1])[0]=((float[]) param.args[1])[0]+1000*WechatStepCount;
WechatStepCount+=1;
…
另外我們還可以使用一些感測器的介面獲取一些數據的信息:
Sensor ss = ((SparseArray<Sensor>) field.get(0)).get(handle);
XposedBridge.log(" SensorEvent: sensor=" + ss);
比如說x就代表開機以來行走的步數,timestamp是獲取步數時候的時間戳等。
另外,我們不僅在android上可以hook計步器,在iOS上也是可以通過越獄後hook iHealth的API介面達到同樣的作弊效果,有興趣的同學可以繼續研究。
『肆』 android如何實現陀螺儀 sensor 在 android 嗎
設備中的三自由度Orientation
Sensor就是一個可以識別設備相對於地面,繞x、y、z軸轉動角度的感應器(自己的理解,不夠嚴謹)。智能手機,平板電腦有了它,可以實現很多好玩的應用,比如說指南針等。
我們可以用一個磁場感應器(magnetic sensor)來實現。
磁場感應器是用來測量磁場感應強度的。一個3軸的磁sensor
IC可以得到當前環境下X、Y和Z方向上的磁場感應強度,對於Android中間層來說就是讀取該感應器測量到的這3個值。當需要時,上報給上層應用程序。磁感應強度的單位是T(特斯拉)或者是Gs(高斯),1T等於10000Gs。
先來看看android定義的坐標系,在/hardware/libhardware/include/hardware/sensors.h中有個圖。
求z和x的反正切可得到此值。
sensors.h中還定義了其他各種sensor。要實現的就是這兩個:
#define SENSOR_TYPE_MAGNETIC_FIELD 2
#define SENSOR_TYPE_ORIENTATION 3
在/hardware/sensors/sensors.cpp 中添加對MAGNETIC_FIELD和ORIENTATION 的支持
『伍』 什麼叫 sensor android
sensor android 就是安卓的感測器,例如:重力感應、陀螺儀
Sensor作為Android系統的一個輸入設備,對Android設備來說是必不可少的。Sensor主要包括G-Sensor、LightsSensor、ProximitySensor、TemperatureSensor等。這里主要對G-Sensor模塊進行解析。
希望能幫到你
『陸』 android sensor怎樣創建設備節點
在Android中,由於沒有mdev和udev,所以它沒有辦法動態的生成設備節點,那麼它是如何做的呢?
我們可以在system/core/init/下的init.c和devices.c中找到答案:
init.c中
在Android中,沒有獨立的類似於udev或者mdev的用戶程序,這個功能集成到了init中做了。代碼見:system/core/init/init.c文件,如下:
if (ufds[0].revents == POLLIN)
handle_device_fd(device_fd);
其中handle_device_fd(device_fd)函數在system/core/init/devices.c中實現,參數device_fd 由函數device_init()->open_uevent_socket()->socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)函數調用返回。
函數handle_device_fd(device_fd)中,根據傳進來的device_fd參數,調用recv(fd, msg, UEVENT_MSG_LEN, 0)函數,將內核探測到的設備並通過NETLINK機制傳過來的socket描述符轉化成消息。接著調用parse_event(msg, &uevent);函數將消息翻譯成uevent事件,並將改事件傳遞給handle_device_event(&uevent)函數。
handle_device_event(&uevent)函數中,依據參數uevent->subsystem類型創建dev下的相應目錄,如:/dev/graphics。緊接著根據uevent->action是"add"還是"remove"來實現設備節點的創建與刪除。如果uevent->action是"add",則調用make_device(devpath, block, uevent->major, uevent->minor)函數生成設備節點。如果uevent->action是"remove",則調用unlink(devpath)對設備節點進行刪除。
『柒』 android手機都有哪些sensor
1.Sensor Type
重力感應/加速度感測器 (G-Sensor)
光感應 (Light-Sensor)
溫度感應
方向感應
磁場、
臨近性
2.如何實現Sensor編程
a.獲取系統服務(SENSOR_SERVICE)返回一個SensorManager 對象
sensormanager = (SensorManager)getSystemSeriver(SENSOR_SERVICE);
b.通過SensorManager對象獲取相應的Sensor類型的對象
sensorObject = sensormanager.getDefaultSensor(sensor Type);
c.聲明一個SensorEventListener 對象用於偵聽Sensor 事件,並重載onSensorChanged方法
SensorEventListener sensorListener = new SensorEventListener(){
};
d.注冊相應的SensorService
sensormanager.registerListener(sensorListener, sensorObject, Sensor TYPE);
e.銷毀相應的SensorService
sensormanager.unregisterListener(sensorListener, sensorObject);
f: SensorListener 介面是感測器應用程序的中心。它包括兩個必需方法:
onSensorChanged(int sensor,float values[]) 方法在感測器值更改時調用。
該方法只對受此應用程序監視的感測器調用(更多內容見下文)。該方法的參數包括:一個整數,指示更改的感測器;一個浮點值數組,表示感測器數據本身。有些感測器只提供一個數據值,另一些則提供三個浮點值。方向和加速表感測器都提供三個數據值。
當感測器的准確性更改時,將調用 onAccuracyChanged(int sensor,int accuracy) 方法。參數包括兩個整數:一個表示感測器,另一個表示該感測器新的准確值。
3.關於G-Sensor
Android 加速度感測器的類型是 Sensor.TYPE_ACCELEROMETER
通過 android.hardware.SensorEvent 返回加速度感測器值。
加速度感測器返回值的單位是加速度的單位 m/s^2(米每二次方秒),有三個方向的值分別是
values[0]: x-axis 方向加速度
values[1]: y-axis 方向加速度
values[2]: z-axis 方向加速度
其中x,y,z方向的定義是以水平放置在的手機的右下腳為參照系坐標原點
x 方向就是手機的水平方向,右為正
y 方向就是手機的水平垂直方向,前為正
y 方向就是手機的空間垂直方向,天空的方向為正,地球的方向為負
需要注意的是,由於地球固有的重力加速度g (值為9.8 m/s^2),
因此現實中實際加速度值應該是 z方向返回值 - 9.8 m/s^2.
比如你以 2 m/s^2 的加速度將手機拋起,這時z方向的返回值應該是 11.8 m/s^2.
反之若以手機以2 m/s^2 的加速度墜落,則z方向的返回值應該是 7.8 m/s^2.
x,y方向則沒有上述限制。
『捌』 在android上面 如何 通過sensor來獲取手機當前的運動方向
不知道是不是你想要的。
package com.yarin.android.Examples_09_01;
import java.util.List;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class Activity01 extends Activity implements SensorEventListener
{
private boolean mRegisteredSensor;
//定義SensorManager
private SensorManager mSensorManager;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mRegisteredSensor = false;
//取得SensorManager實例
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
@Override
protected void onResume()
{
super.onResume();
//接受SensorManager的一個列表(Listener)
//這里我們指定類型為TYPE_ORIENTATION(方向感應器)
List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0)
{
Sensor sensor = sensors.get(0);
//注冊SensorManager
//this->接收sensor的實例
//接收感測器類型的列表
//接受的頻率
mRegisteredSensor = mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
}
}
@Override
protected void onPause()
{
if (mRegisteredSensor)
{
//如果調用了registerListener
//這里我們需要unregisterListener來卸載\取消注冊
mSensorManager.unregisterListener(this);
mRegisteredSensor = false;
}
super.onPause();
}
//當進準度發生改變時
//sensor->感測器
//accuracy->精準度
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
// 當感測器在被改變時觸發
@Override
public void onSensorChanged(SensorEvent event)
{
// 接受方向感應器的類型
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
//這里我們可以得到數據,然後根據需要來處理
//由於模擬器上面無法測試效果,因此我們暫時不處理數據
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
}
}
}
『玖』 android 非上層程序怎麼調用sensor
Android上層應用apk到G-sensor driver的大致流程: Android HAL層,即硬體抽象層,是Google響應廠家「希望不公開源碼」的要求推出的新概念 1,源代碼和目標位置 源代碼: /hardware/libhardware目錄,該目錄的目錄結構如下: /hardware/libhardware/hardware.c編譯成libhardware.so,目標位置為/system/lib目錄 /hardware/libhardware/include/hardware目錄下包含如下頭文件: hardware.h 通用硬體模塊頭文件 bit.h bit模塊頭文件 gralloc.h gralloc模塊頭文件 qemud.h qemud模塊頭文件 sensors.h 感測器模塊頭文件 /hardware/libhardware/moles目錄下定義了很多硬體模塊 這些硬體模塊都編譯成xxx.xxx.so,目標位置為/system/lib/hw目錄 2,Android對於Sensor的API定義在 hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供以下8個API函數 [控制方面] int (*open_data_source)(struct sensors_control_device_t *dev); int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled); int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms); int (*wake)(struct sensors_control_device_t *dev); [數據方面] int (*data_open)(struct sensors_data_device_t *dev, int fd); int (*data_close)(struct sensors_data_device_t *dev); int (*poll)(struct sensors_data_device_t *dev, sensors_data_t* data); [模塊方面] int (*get_sensors_list)(struct sensors_mole_t* mole, struct sensor_t const** list); 在Java層Sensor的狀態控制由SensorService來負責,它的java代碼和JNI代碼分別位於: frameworks/base/services/java/com/Android/server/SensorService.java frameworks/base/services/jni/com_Android_server_SensorService.cpp 在Java層Sensor的數據控制由SensorManager來負責,它的java代碼和JNI代碼分別位於: frameworks/base/core/java/Android/hardware/SensorManager.java frameworks/base/core/jni/Android_hardware_SensorManager.cpp Android framework中與sensor通信的是sensorService.java和sensorManager.java。 sensorService.java的具體通信是通過JNI調用sensorService.cpp中的方法實現的。 sensorManager.java的具體通信是通過JNI調用sensorManager.cpp中的方法實現的。 sensorService.cpp和sensorManger.cpp通過hardware.c與sensor.so通信。其中sensorService.cpp實現對sensor的狀態控制,sensorManger.cpp實現對sensor的數據控制。 sensor.so通過ioctl控制sensor driver的狀態,通過打開sensor driver對應的設備文件讀取G-sensor採集的數據。 Android SDK提供了4個類來於sensor通信,分別為 sensor,sensorEvent,sensorEventListener,sensorManager。其中 sensorEventListener用來在sensorManager中注冊需要監聽的sensor類型。 sensorManager.java提供registrater(),unregistrater()介面供sensorEventListener使用。 sensorManager.java不斷輪詢從sensor.so中取數據。取到數據後送給負責監聽此類型sensor的 sensorEventListener.java。sensorEventListener.java通過在sensorManager.java中注冊可以監聽特定類型的sensor傳來的數據。 系統啟動時執行systemProcess,會啟動sensorService.java,在sensorService.java的構造函數中調用JNI方法_sensor_control_init()。 sensorService.cpp中相應的方法Android_int()會被執行。該函數會調用hardware.c中的方法hw_get_mole()此函數又通過調用load()函數在system/lib/hw下查找sensor.so 查找時會根據harware.c中定義好的sensor.*.so的擴展名的順序查找,找到第一個匹配的時候即停止,並將該sensor.so中定義好的一個全局變數HAL_MODULE_INFO_SYM帶回。該變數包含的一個 重要信息是它的一個成員結構變數中包含的一個函數指針open,該指針所指函數會對一個device結構變數賦值,從而帶出sensorService.cpp和sensorManager.cpp與sensor通信所需要的全部信息。 device結構變數有兩種變體分別供sensorService.cpp和sensorManaer.cpp使用。其中主要是一些函數指針指向與sensor通信的函數。 sensorService.cpp和sensorManager.cpp在得到HAL_MODULE_INFO_SYM結構後都會調用 sensors.h的inline函數open()通過HAL_MODULE_INFO_SYM的open函數指針將所需的device信息取回。 系統在啟動activityManager.java時,它會啟動sensorManager.java,它也會調用hardware.c中的方法hw_get_mole()帶回HAL_MODULE_INFO_SYM。
『拾』 android 判斷是否有gsensor
Android中sensor在Android系統架構中的位置及其工作。方框圖如下:
從以上方框圖中,可以看出Android中sensor在系統分為四層:驅動層(Sensor Driver)、硬體抽象層(Native)、中間層(Framework)、應用層(Java)。硬體抽象層與中間層可以合並一起作為Framework層。
針對我們xx這里一個具體的Gsensor,下面將以具體的源碼形式來講解以上的這個系統框圖。