Android之感應器系統(Gsensor) .

來源:互聯網
上載者:User

最近在解關於Gsensor的Bug,Bug還沒解掉,反而把Android的Gsensor流程走了一遍。好久不寫部落格了,不能偷懶啊,學了東西還是得總結一下,好讓後來人不要費多少工夫,同時拋磚引玉,大家一起討論一下,有什麼錯誤我好糾正一下,對自己也是一種激勵。言歸正傳,本文主要從上層的Activity一直分析到kernel的driver,路比較長,不過我喜歡搞清楚架構。

目錄:

一、應用程式層的API;

二、Framwork中的處理;

三、C++中的JNI;

四、Kernel的Gsensor-driver;

 

一、應用程式層的API

 

先看一個例子,這個例子是Gsensor的最簡單應用,只是用來列印x,y,z的三個值:

[java]
view plaincopyprint?
  1. public class main extends Activity {    
  2.     private float x, y, z;    
  3.     protected void onCreate(Bundle savedInstanceState) {    
  4.         super.onCreate(savedInstanceState);   
  5.         SensorManager mSensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);   
  6.         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);  
  7.         SensorEventListener lsn = new SensorEventListener() {  
  8.   
  9.                     public void onSensorChanged(SensorEvent e) {  
  10.                             System.out.println(e.value[0]);  
  11.                             System.out.println(e.value[1]);  
  12.                             System.out.println(e.value[2]);  
  13.                      }  
  14.                     public void onAccuracyChanged(Sensor s, int accuracy) {  
  15.                     }      
  16.                };  
  17.                mSensorManager.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  
  18. }  

public class main extends Activity {<br /> private float x, y, z;<br /> protected void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> SensorManager mSensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);<br /> Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);<br /> SensorEventListener lsn = new SensorEventListener() {</p><p> public void onSensorChanged(SensorEvent e) {<br /> System.out.println(e.value[0]);<br /> System.out.println(e.value[1]);<br /> System.out.println(e.value[2]);<br /> }<br /> public void onAccuracyChanged(Sensor s, int accuracy) {<br /> }<br /> };<br /> mSensorManager.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);<br />}<br />  

    這段代碼中我們重點關注這幾個類:SensorManager,SensorEvent;然後我們進入到Framework中看看這兩個類是如何?,它們都做了什麼操作。

 

二、Framework中的處理

    相關檔案:/frameworks/base/core/java/android/hardware/SensorManager.java;

    這個SensorManager主要負責返回感應器類型,從底層獲得資料。getSystemService(String name)是根據名字返回相應的Manager,這個機制也比較重要,網上有相關資料,在此不展開討論了;mSensorManager.getDefaultSensor(type)就是擷取指定類型的感應器。這些類型在API手冊中都能查到,包括溫度感應器,重力感應器等。registerListener註冊監聽器,這是為了能讓ManagerSensor回調正確的介面函數,註冊的時候我們可以指定sensor的靈敏度,分四個等級,API手冊中有相應介紹。我們來看一下SensorManager的建構函式:

     1.擷取windowManager執行個體,監控旋轉螢幕狀態;

     2.初始化sensorList感應器列表;調用了sensors_module_init()和sensors_module_get_next_sensor()兩個本地JNI方法;

     3.構造SensorThread線程(這裡線程並沒有開啟);

      系統中只維護了一個SensorManager,應用程式層的調用只是往SensorManager裡面註冊了一個監聽介面,然後使能相應的Sensor,設定Sensor的參數;SensorManager的擷取是通過調用getSystemService方法,這個方法會檢測SensorManager是否已經存在了,如果存在了一個執行個體就直接返回這個執行個體。

     下面重點分析一下SensorThread線程,這個線程的開啟是在registerListener裡面,SensorThread是一個死迴圈,他通過調用native方法sensors_data_poll方法來輪詢下層發來的感應器資料。每次接受到一個資料就會調用代理listener中的onSensorChangedLocked方法,把它封裝成一個訊息發給自己的messagerHandler,在這裡面最終調用註冊的onSensorChanged方法,也就是我們上面應用程式介面的中方法。

 

 

三、C++中的JNI

     相關檔案:/frameworks/base/core/jni/android_hardware_SensorManager.cpp;

     sensors_module_init()模組初始化-->hw_get_module()-->load(),其實就是把sensor.so的連結庫載入進來;

     sensor.so是與機器相關的hardware層來實現的,要在hardware下實現相應的sensor.cpp;這個檔案就是跟kernel打交道的最底層的檔案了。裡面主要完成了開啟裝置檔案,讀取裝置節點的資料。比如我們的Gsensor是走的輸入輸出子系統,就開啟相應的event檔案來讀取驅動上報的座標資料。

    

    

 

四、Kernel中的驅動

     這個我們的實現比較簡單,是走的input子系統。你可以選擇用中斷模式或者輪詢模式來讀取裝置發來的資料。

 

五、SensorService(對比SensorManager)

     其實還有一個非常重要的類沒有說,就是SensorService;現在有必要把整個Sensor總結分析一下了。

     系統開啟之後會依次啟動各種系統服務;源碼在SystemServer.java中,在這裡系統會new一個SensorService,SensorService中會調用JNI方法_sensors_control_init,對應com_android_server_SersorService.cpp中的android_init();這個主要是初始化SensorDevice的控制代碼供以後調用;下面是com_android_server_SersorService.cpp註冊的JNI方法:

    

[java]
view plaincopyprint?
  1. static JNINativeMethod gMethods[] = {  
  2.     {"_sensors_control_init",     "()I",   (void*) android_init },  
  3.     {"_sensors_control_open",     "()Landroid/os/Bundle;",  (void*) android_open },  
  4.     {"_sensors_control_close",     "()I",  (void*) android_close },  
  5.     {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },  
  6.     {"_sensors_control_wake",     "()I", (void*) android_data_wake },  
  7.     {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },  
  8. };  

static JNINativeMethod gMethods[] = {<br /> {"_sensors_control_init", "()I", (void*) android_init },<br /> {"_sensors_control_open", "()Landroid/os/Bundle;", (void*) android_open },<br /> {"_sensors_control_close", "()I", (void*) android_close },<br /> {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },<br /> {"_sensors_control_wake", "()I", (void*) android_data_wake },<br /> {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },<br />};

    從這裡我們可以看出,SensorService這個類主要是負責控制Sensor裝置的。這些JNI函數最終都會調用到我們Sensor.cpp裡面的實現。對比我們的SensorManager中JNI的註冊:

   

[java]
view plaincopyprint?
  1. static JNINativeMethod gMethods[] = {  
  2.     {"nativeClassInit", "()V",              (void*)nativeClassInit },  
  3.     {"sensors_module_init","()I",           (void*)sensors_module_init },  
  4.     {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",  
  5.                                             (void*)sensors_module_get_next_sensor },  
  6.     {"sensors_data_init", "()I",            (void*)sensors_data_init },  
  7.     {"sensors_data_uninit", "()I",          (void*)sensors_data_uninit },  
  8.     {"sensors_data_open",  "([Ljava/io/FileDescriptor;[I)I",  (void*)sensors_data_open },  
  9.     {"sensors_data_close", "()I",           (void*)sensors_data_close },  
  10.     {"sensors_data_poll",  "([F[I[J)I",     (void*)sensors_data_poll },  
  11. };  

static JNINativeMethod gMethods[] = {<br /> {"nativeClassInit", "()V", (void*)nativeClassInit },<br /> {"sensors_module_init","()I", (void*)sensors_module_init },<br /> {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",<br /> (void*)sensors_module_get_next_sensor },<br /> {"sensors_data_init", "()I", (void*)sensors_data_init },<br /> {"sensors_data_uninit", "()I", (void*)sensors_data_uninit },<br /> {"sensors_data_open", "([Ljava/io/FileDescriptor;[I)I", (void*)sensors_data_open },<br /> {"sensors_data_close", "()I", (void*)sensors_data_close },<br /> {"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },<br />};

    不難看出,SensorManager主要負責的是資料的傳輸;

    OK,到這裡Sensor基本就分析完了。其中WindowManager跟Sensor打交道,實現轉屏等操作,這裡就先不做分析了。本人水平有限,接觸android也就兩個月的時間,有什麼不對或者欠妥的地方歡迎指正。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.