中文字幕第二一区_久久久久在线视频_精品国产自在现线看久久_亚洲精品一区二区三区电影网

產品分類

當前位置: 首頁 > 工業電子產品 > 集成電路(ICs) > IC傳感器

類型分類:
科普知識
數據分類:
IC傳感器

android 傳感器 源碼:Android傳感器源碼分析(AOSP)

發布日期:2022-05-11 點擊率:70


android 傳感器 源碼:Android傳感器源碼分析(AOSP)  第1張

android 傳感器 源碼:Android傳感器源碼分析(AOSP)

簡介
上一節制作了一個傳感器的應用,應用程序獲取傳感器數據代碼流程大致如下

源碼分析
如上所示,在應用層調用幾個常用接口就能夠獲取到傳感器數據了,主要接口包括

下面對這四個接口為主線來學習源代碼,理解傳感器的框架

getSystemService
該接口是一個用來獲取系統服務的接口,SensorManager是一個抽象類,為應用層提供傳感器接口,SystemSensorManager繼承SensorManager實現了這些接口功能,我們來看一下SystemSensorManager的創建.

SystemSensorManager在SystemServiceRegistry的靜態初始化塊當中,因此在系統初始階段加載SystemServiceRegistry時,SystemSensorManager就會被創建,來看一下它的構造函數

調用nativeCreate創建Native層的SensorManager,在創建過程中會循環等待SensorService被創建,與其建立binder關系,接著調用SensorSerivce的getSensorList,來獲取硬件傳感器列表信息.

上面SensorManager會等待SensorService注冊,將它保存在成員變量mSensorServer中.小結一下這一段流程UML圖

SensorManager功能都來自于SensorService,它在Android的Sensor框架中占據核心位置,接下來看一下分析一下SensorService的相關代碼.
當內核啟動后執行init 程序,該程序解析 init.rc文件(zygote包含在init.${ro.zygote}.rc中),rc文件中指定的應用程序在app_main.cpp中,調用AndroidRuntime的start方法,接著通過JNI調用Zyoteinit.java中的main函數,從這里開始追蹤.

上面代碼可知ZygoteInit的main函數執中調用startSystemServer函數,調用forkSystemServer創建系統服務,跳轉到SystemServer的main函數

在 SystemServer 的main函數中,會創建SystemService對象,并調用run方法,在run方法中調用startBootstrapServices(),接著調用Native方法startSensorService(),

在android_server_SystemServer_startSensorService中創建線程start_sensor_service來實例化SensorService,然后將SensorService添加到ServiceManager當中(SensorManager從ServiceManager里獲取SensorService).當SensorService被創建時,onFirstRef被調用,這個初始化函數完成了一些重要的初始化過程,我們來看一下

在 SensorService 的 onFirstRef 接口中,獲取SensorDevice(單例類)的引用,這里看一下SensorDevice的構造函數

SensorDevice調用 hw_get_module接口加載HAL的Sensor庫庫,接著調用HAL層提供的open接口,執行HAL層的初始化,同時返回硬件訪問接口,接著調用 Sensor HAL提供的 get_sensors_list 接口,獲取所支持的 Sensor列表.
接著上面SensorService::onFirstRef接口,通過SensorDevice獲取傳感器列表信息后,調用registerSensor分別將傳感器添加到mSensors中.然后創建 Looper , Looper用來監聽傳感器數據的上報和分發,接著調用run方法,啟動threadLoop,輪詢HAL層傳感器數據的上報.來看一下SensorService的threadLoop

SensorService的流程圖

getDefaultSensor/getSensorList
SensorManager.java中的getDefaultSensor方法是依賴getSensorlist實現的,來看一下getSensorlist方法.

registerListener
SensorManager.java向應用提供的registerListener方法,最終會調到SystemSensorManager中的registerListenerImpl方法,

創建一個與looper,listener相關聯的SensorEventQueue,看一下SensorEventQueue的構造函數,

接著看它的基類baseEventQueue和它的nativeInitbaseEventQueue方法.

nativeInitSensorEventQueue中,有兩件事要注意,1.創建SensorEventQueue對象2.創建Receiver.先看一下SensorEventQueue的創建

SensorManager通過mSensorServer(它是在SensorManager構造函數里getService獲得)的createSensorEventConnection接口,創建一個SensorEventConnection對象,它是SensorService的內部類,在SensorService::enable中被添加,用來在接收到的HAL層的數據發送出去的重要通道.接著創建一個與這個SensorEventConnection對象關聯的SensorEventQueue對象,并返回.Native層的SensorEventQueue是非常重要的數據通道,一方面接收Native層SensorService發送過來的數據(SensorService的數據來自HAL層),另一方面將數據分發到framewrok層SystemSensorManager的baseEventQueue子類對象中.后面會通過代碼說明這個過程如何發生.接著看Receiver類,Receiver構造函數

Receiver構造函數中,主要建立與SensorService和MessageQueue之間的關聯,接著看它的onFirstRef.

Native層的MessageQueue調用Looper類的addFd方法,添加對SensorEventQueue的監聽,看一下looper的addFd方法.

Receiver繼承LooperCallback并實現了handleEvent函數,addFD時會將callback傳入Looper.Looper的addFd如果被監控的文件描述符,已經存在用EPOLL_CTL_MOD參數調用epoll_ctl修改,否則,EPOLL_CTL_ADD來添加.(Native層的Looper是以epoll為核心實現的,對Looper不熟悉的可以看一下epoll的簡介).Looper在添加文件描述符后,后續通過pollOnce或pollAll接口來訪問,最終都會調用pollInner來等待這些文件描述符被寫入數據,我們來看一下pollInner

在Looper中epoll_wait來監聽文件描述符是否有數據寫入,當有數據寫入后,調用callback的handleEvent方法來進行處理,這里是調用了Receiver的handleEvent方法,handleEvent中依賴于SensorEventQueue中的mSensorChannel(mSensorChannel是在SensorEventConnection構造時創建的)來實現數據的讀取的,mSensorChannel是一個BitTube對象,BitTube提供全雙工的跨進程的通訊管道(這里對它做了一個說明,有興趣可以了解一下),handleEvent依賴它來獲取發送過來的數據(數據從哪發來?我們后面再說),我們看一下Receiver的handleEvent接口

上面會根據不同類型的傳感器將數據進行處理,常用傳感器通過 gbaseEventQueueClassInfo.dispatchSensorEvent進行分發,這里實際上是調用的framework層的SensorEventQueue類(繼承baseEventQueue)的dispatchSensorEvent方法.

dispatchSensorEvent里,通過handle找到對應的sensor,將數據通過SensorEventListener的onSensorChanged將數據給應用程序.
回顧一下前面的流程,Looper通過epoll_wait將數據讀出,回調Receiver的handleEvent函數,handleEvent調用SensorEventQueuem的read方法讀取數據,然后通過JNI回調framework層SensorEventQueue的dispatchSensorEvent方法,在dispatchSensorEvent方法中回調SensorEventListener的onSensorChanged方法,這個方法為應用注冊的監聽方法,將數據返回到應用層.可是是誰將數據寫入Looper監控的文件描述符中的?我們接著看一下這個過程.之前說過”handleEvent調用SensorEventQueue的read方法讀取數據”,讀取和寫入都依賴于BitTube對象,它在SensorEventConnection構造函數中創建(mChannel),然后SensorEventQueue通過getSensorChannel()接口獲取該對象,(這里可以按照mSensorChannel的線索,反推寫入數據的地方,接下來直接描述結果),SensorService在onFirstRef最后執行了run,threadLoop開始運行,這個函數上面分析過了,在最后時

SensorEventConnection的sendEvents方法會將數據寫入BitTube中

到這里傳感器數據的寫入,讀取流程分析完畢.
這里在簡述一下數據的完整流程:SensorService的threadLoop線程,循環通過SensorDevice的poll接口,從HAL層獲取傳感器數據,然后調用已建立好的傳感器連接通道SensorEventConnection的sendEvents方法,寫入到BitTube的socketpai通道中,Looper函數的epoll_wait被喚醒,然后回調Receiver的handleEvent方法,在該方法中SensorEventQueue會讀取socketpai通道里的數據,調用JNI調用framework層的SensorEventQueue的dispatchSensorEvent方法,在此方法中回調SensorEventListener的onSensorChanged方法和onAccuracyChanged,這兩個方法就是應用程序注冊的方法.
傳感器HAL層的AOSP部分包括sensor.h,接下來看一下這個文件內容.

HAL層關鍵結構和接口
HAL層中關鍵的結構和接口存在sensor.h文件中,包括:sensor_module_t、sensors_poll_device_1、get_sensors_list等

sensor.h
sensor_module_t

sensors_poll_device_1

sensors_poll_device_1_t兼容老1.0版本sensors_poll_device_t,并提供了新版本接口batch,flush,inject_sensor_data接口.
- get_sensors_list

獲取所有sensor的列表,由*list指向,傳遞給上層使用.又的平臺是靜態方式注冊list,有的平臺動態方式注冊.

set_operation_mode

模式設置接口,用來將sensor service注入的數據返回.因傳感器數據來自于底層硬件,這個方式多用于調試或特殊功能,多數平臺不實現這個接口.

sensor_t

這個結構體在實現hal層代碼時,參數已又英文注釋,重點關注handle、type、minDelay、flags.

sensors_event_t

傳感器數據上報的結構體,注意sensor和sensors_vec_t,sensor變量對應的是handle,如果不匹配將無法被上層enable,sensors_vec_t中的status默認為0,需要設置為大于0的狀態,否則上層會將數據丟棄,status可選參數如下

HAL層以下部分各SOC廠商實現方式不同(有些走input,有些走IIO,有些走share memory),這里不繼續追述.

android 傳感器 源碼:android各傳感器開發,顯示返回數據 碼農集市專業分享IT編程學習資源

關于碼農集市

本站旨在為廣大IT學習愛好者提供一個非營利性互相學習交流分享平臺。本站所有資源都可以被免費獲取學習研究。本站資源來自網友分享,僅供學習研究,請務必在下載后24小時內給予刪除,不得用于其他任何用途,否則后果自負。基于互聯網的特殊性,coder100無法對用戶傳輸的作品、信息、內容的權屬或合法性、安全性、合規性、真實性、科學性、完整權、有效性等進行實質審查;無論coder100經營者是否已進行審查,用戶均應自行承擔因其傳輸的作品、信息、內容而可能或已經產生的侵權或權屬糾紛等法律責任。本站所有資源不代表本站的觀點或立場,基于網友分享,根據中國法律《信息網絡傳播權保護條例》第二十二條之規定,若資源存在侵權或相關問題請聯系本站客服人員,#qq.com,請把#換成@,本站將給予最大的支持與配合,做到及時反饋和處理。關于更多版權及免責申明參見  版權及免責申明

android 傳感器 源碼:[實戰示例] 帶您深入探討 Android 傳感器【附源碼】

轉自:
Android 是一個面向應用程序開發的富平臺,它擁有許多具有吸引力的用戶界面元素和數據管理功能。Android 還提供了一組豐富的接口選項。
在本文中,學習如何配合使用 Android 的各種傳感器選項監控您的環境。樣例代碼展示了如何在 Android 電話中錄制音頻。想構建自己的監視器嗎?想用聲音來接聽電話或者打開房門嗎?請學習如何利用配備有 Android 的設備的硬件功能。
對于 Java? 開發人員來說,Android 平臺是通過使用硬件傳感器創建創新應用程序的理想平臺。我們將學習一些可用于 Android 應用程序的接口連接選項,包括使用傳感器子系統和錄制音頻片段。
利用配備 Android 的設備的硬件功能可以構建哪些應用程序呢?任何需要電子監視和監聽的應用程序都可以構建。嬰兒監視器、安全系統,甚至地震儀都可以。理論上講,您不能同時出現在兩個地方,但 Android 可以利用一些可行的方法實現這一點。縱觀本文始末,您必須記住,使用的 Android 設備不僅僅局限于 “手機”,還可以是部署在固定位置、具有無線網絡連接的設備,比如 EDGE 或 WiFi。請下載附件中本文示例的源代碼。
Android 傳感器功能
使用 Android 平臺有一個很新穎的地方,那就是您可以在設備內部訪問一些“好工具”。過去,訪問設備底層硬件的能力一度讓移動開發人員感到非常棘手。盡管 Android Java 環境的角色仍然是您和設備的橋梁,但Android 開發團隊讓許多硬件功能浮出了水面。該平臺是一個開源平臺,因此您可以自由地編寫代碼實現您的任務。
如果尚未安裝 Android,您可以 下載     Android SDK。您還可以 瀏覽 android.hardware 包的內容并參考本文的示例。android.media 包 包含了一些提供有用和新穎功能的類。
Android SDK 中包含的一些面向硬件的功能描述如下。
表 1. Android SDK 中提供的面向硬件的特性
特性
描述
android.hardware.Camera
允許應用程序與相機交互的類,可以截取照片、獲取預覽屏幕的圖像,修改用來治理相機操作的參數。
android.hardware.SensorManager
允許訪問 Android 平臺傳感器的類。并非所有配備 Android 的設備都支持 SensorManager 中的所有傳感器,雖然這種可能性讓人非常興奮。(可用傳感器的簡介見下文)
android.hardware.SensorListener
在傳感器值實時更改時,希望接收更新的類要實現的接口。應用程序實現該接口來監視硬件中一個或多個可用傳感器。例如,本文中的 代碼 包含實現該接口的類,實現后可以監視設備的方向和內置的加速表。
android.media.MediaRecorder
用于錄制媒體樣例的類,對于錄制特定位置(比如嬰兒保育)的音頻活動非常有用。還可以分析音頻片段以便在訪問控件或安全應用程序時進行身份鑒定。例如,它可以幫助您通過聲音打開門,以節省時間,不需要從房產經紀人處獲取鑰匙。
android.FaceDetector
允許對人臉(以位圖形式包含)進行基本識別的類。不可能有兩張完全一樣的臉。可以使用該類作為設備鎖定方法,無需記密碼 — 這是手機的生物特征識別功能。
android.os.*
包含幾個有用類的包,可以與操作環境交互,包括電源管理、文件查看器、處理器和消息類。和許多可移動設備一樣,支持 Android 的電話可能會消耗大量電能。讓設備在正確的時間 “醒來” 以監視感興趣的事件是在設計時需要首先關注的方面。
java.util.Date
java.util.Timer
java.util.TimerTask
當測量實際的事件時,數據和時間往往很重要。例如,java.util.Date 類允許您在遇到特定的事件或狀況時獲取時間戳。您可以使用 java.util.Timer 和 java.util.TimerTask 分別執行周期性任務或時間點任務。

android.hardware.SensorManager 包含幾個常量,這表示 Android 傳感器系統的不同方面,包括:傳感器類型方向、加速表、光線、磁場、臨近性、溫度等。采樣率最快、游戲、普通、用戶界面。當應用程序請求特定的采樣率時,其實只是對傳感器子系統的一個提示,或者一個建議。不保證特定的采樣率可用。準確性高、低、中、不可靠。
SensorListener 接口是傳感器應用程序的中心。它包括兩個必需方法:
onSensorChanged(int sensor,float values[]) 方法在傳感器值更改時調用。該方法只對受此應用程序監視的傳感器調用(更多內容見下文)。該方法的參數包括:一個整數,指示更改的傳感器;一個浮點值數組,表示傳感器數據本身。有些傳感器只提供一個數據值,另一些則提供三個浮點值。方向和加速表傳感器都提供三個數據值。
當傳感器的準確性更改時,將調用 onAccuracyChanged(int sensor,int accuracy) 方法。參數包括兩個整數:一個表示傳感器,另一個表示該傳感器新的準確值。

要與傳感器交互,應用程序必須注冊以偵聽與一個或多個傳感器相關的活動。注冊使用 SensorManager 類的 registerListener 方法完成。本文中的源代碼中演示了如何注冊和注銷 SensorListener。
記住,并非所有支持 Android 的設備都支持 SDK 中定義的所有傳感器。如果某個傳感器無法在特定的設備上使用,您的應用程序就會適當地降級。
傳感器示例
樣例應用程序僅監控對方向和加速表傳感器的更改(見源代碼)。當收到更改時,傳感器值在 TextView 小部件的屏幕上顯示。
圖 1 展示了該應用程序的運行情況。
圖 1.  監視加速和方向

使用 Eclipse 環境和 Android Developer Tools 插件創建的應用程序。清單 1 展示了該應用程序的代碼。
清單 1. IBMEyes.java

package com.msi.ibm.eyes;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.hardware.SensorManager;
import android.hardware.SensorListener;
public class IBMEyes extends Activity implements SensorListener {
final String tag="IBMEyes";
SensorManager sm=null;
TextView xViewA=null;
TextView yViewA=null;
TextView zViewA=null;
TextView xViewO=null;
TextView yViewO=null;
TextView zViewO=null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
  // get reference to SensorManager
sm=(SensorManager) getSystemService(SENSOR_SERVICE);
setContentView(R.layout.main);
xViewA=(TextView) findViewById(R.id.xbox);
yViewA=(TextView) findViewById(R.id.ybox);
zViewA=(TextView) findViewById(R.id.zbox);
xViewO=(TextView) findViewById(R.id.xboxo);
yViewO=(TextView) findViewById(R.id.yboxo);
zViewO=(TextView) findViewById(R.id.zboxo);
}
public void onSensorChanged(int sensor, float[] values) {
synchronized (this) {
Log.d(tag, "onSensorChanged: " + sensor + ", x: " +
values[0] + ", y: " + values[1] + ", z: " + values[2]);
if (sensor==SensorManager.SENSOR_ORIENTATION) {
xViewO.setText("Orientation X: " + values[0]);
yViewO.setText("Orientation Y: " + values[1]);
zViewO.setText("Orientation Z: " + values[2]);
}
if (sensor==SensorManager.SENSOR_ACCELEROMETER) {
xViewA.setText("Accel X: " + values[0]);
yViewA.setText("Accel Y: " + values[1]);
zViewA.setText("Accel Z: " + values[2]);
}
}
}

public void onAccuracyChanged(int sensor, int accuracy) {
Log.d(tag,"onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
}
@Override
protected void onResume() {
super.onResume();
 // register this class as a listener for the orientation and accelerometer sensors
sm.registerListener(this,
SensorManager.SENSOR_ORIENTATION |SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onStop() {
// unregister listener
sm.unregisterListener(this);
super.onStop();
}
}

編寫應用程序必須基于常見的活動,因為它只是利用從傳感器獲取的數據更新屏幕。在設備可能在前臺執行其他活動的應用程序中,將應用程序構建為服務可能更加合適。
該活動的 onCreate 方法可以引用 SensorManager,其中包含所有與傳感器有關的函數。onCreate 方法還建立了對 6 個 TextView 小部件的引用,您需要使用傳感器數據值更新這些小部件。

onResume() 方法使用對 SensorManager 的引用通過 registerListener 方法注冊傳感器更新:
第一個參數是實現 SensorListener 接口的類的實例。
第二個參數是所需傳感器的位掩碼。在本例中,應用程序從 SENSOR_ORIENTATION 和 SENSOR_ACCELEROMETER 請求數據。
第三個參數是一個系統提示,指出應用程序更新傳感器值所需的速度。

應用程序(活動)暫停后,需要注銷偵聽器,這樣以后就不會再收到傳感器更新。這通過 SensorManager 的 unregisterListener 方法實現。惟一的參數是 SensorListener 的實例。
在 registerListener 和 unregisterListener 方法調用中,應用程序使用關鍵字 this。注意類定義中的 implements 關鍵字,其中聲明了該類實現 SensorListener 接口。這就是要將它傳遞到 registerListener 和 unregisterListener 的原因。

SensorListener 必須實現兩個方法 onSensorChange 和 onAccuracyChanged。示例應用程序不關心傳感器的準確度,但關注傳感器當前的 X、Y 和 Z 值。onAccuracyChanged 方法實質上不執行任何操作;它只在每次調用時添加一個日志項。
似乎經常需要調用 onSensorChanged方法,因為加速表和方向傳感器正在快速發送數據。查看第一個參數確定哪個傳感器在發送數據。確認了發送數據的傳感器之后,將使用方法第二個參數傳遞的浮點值數組中所包含的數據更新相應的 UI元素。該示例只是顯示這些值,但在更加高級的應用程序中,還可以分析這些值,比較原來的值,或者設置某種模式識別算法來確定用戶(或外部環境)的行為。
現在您已經了解了傳感器子系統,接下來的部分將回顧一個在 Android 手機上錄制音頻的代碼樣例。該樣例運行在 DEV1 開發設備上。
使用 MediaRecorder

android.media 包包含與媒體子系統交互的類。使用 android.media.MediaRecorder 類進行媒體采樣,包括音頻和視頻。MediaRecorder 作為狀態機運行。您需要設置不同的參數,比如源設備和格式。設置后,可執行任何時間長度的錄制,直到用戶停止。

清單 2 包含的代碼在 Android 設備上錄制音頻。顯示的代碼不包括應用程序的 UI 元素(見源代碼)。
清單 2. 錄制音頻片段

MediaRecorder mrec ;
File audiofile=null;
private static final String TAG="SoundRecordingDemo";
protected void startRecording() throws IOException
{
  mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
  mrec.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  if (mSampleFile==null)
  {
  File sampleDir=Environment.getExternalStorageDirectory();
  try
  {
 audiofile=File.createTempFile("ibm", ".3gp", sampleDir);
  }
  catch (IOException e)
  {
  Log.e(TAG,"sdcard access error");
  return;
  }
  }
  mrec.setOutputFile(audiofile.getAbsolutePath());
  mrec.prepare();
  mrec.start();
}
protected void stopRecording()
{
  mrec.stop();
  mrec.release();
  processaudiofile(audiofile.getAbsolutePath());
}
protected void processaudiofile()
{
  ContentValues values=new ContentValues(3);
  long current=System.currentTimeMillis();
  values.put(MediaStore.Audio.Media.TITLE, "audio" + audiofile.getName());
  values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
  values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/3gpp");
  values.put(MediaStore.Audio.Media.DATA, audiofile.getAbsolutePath());
  ContentResolver contentResolver=getContentResolver();

Uri base=MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  Uri newUri=contentResolver.insert(base, values);

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, newUri));
}

在 startRecording 方法中,實例化并初始化 MediaRecorder 的實例:
輸入源被設置為麥克風(MIC)。
輸出格式被設置為 3GPP(*.3gp 文件),這是移動設備專用的媒體格式。
編碼器被設置為 AMR_NB,這是音頻格式,采樣率為 8 KHz。NB 表示窄頻。SDK 文檔 解釋了不同的數據格式和可用的編碼器。

音頻文件存儲在存儲卡而不是內存中。External.getExternalStorageDirectory() 返回存儲卡位置的名稱,在該目錄中將創建一個臨時文件名。然后,通過調用 setOutputFile 方法將文件關聯到 MediaRecorder 實例。音頻數據將存儲到該文件中。

調用 prepare 方法完成 MediaRecorder 的初始化。準備開始錄制流程時,將調用 start 方法。在調用 stop 方法之前,將對存儲卡上的文件進行錄制。release 方法將釋放分配給 MediaRecorder 實例的資源。
音頻采樣完成之后,需要采取以下步驟:
向設備的媒體庫添加該音頻。
執行一些模式識別步驟確定聲音:
這是嬰兒的啼哭聲嗎?
這是所有人的聲音嗎?是否要解鎖手機?
這是 “芝麻開門” 嗎?是否要打開通往 “秘密通道” 的大門?
自動將音頻文件上傳到網絡位置以便處理。

在該代碼樣例中,processaudiofile 方法將音頻添加到媒體庫。使用 Intent 通知設備上的媒體應用程序有新內容可用。

關于該代碼片段最后要注意的是:如果您試用,它一開始不會錄制音頻。您將看到創建的文件,但是沒有任何音頻。
您需要向 AndroidManifest.xml 文件添加權限:

現在,您已經學了一點關于與 Android 傳感器和錄制音頻相關的內容。下一節將更全面的介紹與數據采集和報告系統有關的應用程序架構。
Android 作為傳感器平臺

Android 平臺包含各種用于監視環境的傳感器選項。有了輸入或模擬選項數組,以及高級計算和互聯功能,Android 成為構建實際系統的最佳平臺。
圖 2 顯示了輸入、應用程序邏輯、通知方法或輸出之間的簡單視圖。

圖 2. 以 Android 為中心的傳感器系統的方塊圖

該架構很靈活;應用程序邏輯可以劃分為本地 Android 設備和服務器端資源(可以實現更大的數據庫和計算功能)。
例如,本地 Android 設備上錄制的音軌可以 POST 到 Web 服務器,其中將根據音頻模式數據庫比較數據。很明顯,這僅僅是冰山一角。希望您能更深入地研究,讓 Android 平臺超越移動電話的范疇。
結束語

在本文中,我們介紹了 Android 傳感器。樣例應用程序度量了方向和加速,以及使用 MediaRecorder 類與錄制功能進行交互。對于構建實際系統,Android 是一個靈活、有吸引力的平臺。Android 領域發展迅速,并且不斷壯大。請務必關注該平臺。
android 傳感器 源碼:Android傳感器源碼分析(AOSP)  第2張

android 傳感器 源碼:分享一套源碼十多種安卓傳感器如何使用的源碼十分全面

private long lastUpdateTime;
// 手機上一個位置時重力感應坐標
private float lastX;
private float lastY;
private float lastZ;
Vibrator vibrator;
// 速度閾值,當搖晃速度達到這值后產生作用
private static final int SPEED_SHRESHOLD=1000;
// 兩次檢測的時間間隔
private static final int UPTATE_INTERVAL_TIME=70;
private DevicePolicyManager deviceManager;
// private boolean isAdmin;
private PowerManager pm;
public void onSensorChanged(SensorEvent event) {
// 現在檢測時間
long currentUpdateTime= System.currentTimeMillis();
// 兩次檢測的時間間隔
long timeInterval=currentUpdateTime - lastUpdateTime;
// 判斷是否達到了檢測時間間隔
// if (timeInterval < UPTATE_INTERVAL_TIME)        // return;        // 現在的時間變成last時間        lastUpdateTime= currentUpdateTime;        // 獲得x,y,z坐標        float x=event.values[0];        float y=event.values[1];        float z=event.values[2];        // if (Math.abs(x) > 9.0 || Math.abs(y) > 9.0) {
// Log.e("onSensorChanged", Math.abs(x)+"::"+Math.abs(y));
// Log.e("onSensorChanged", isAdmin+"");
// if (!isAdmin) {
// Log.e("onSensorChanged", isAdmin+"");
// deviceManager.lockNow();
// // deviceManager.resetPassword("", 0);
// }
// }
//
// 獲得x,y,z的變化值
float deltaX=x - lastX;
float deltaY=y - lastY;
float deltaZ=z - lastZ;
// Log.e("onSensorChanged", deltaX+
// "::::"+deltaY+"::::::"+deltaZ+"::::"+timeInterval);
// 將現在的坐標變成last坐標
lastX= x;
lastY = y;
lastZ = z;

// double riderSpeed=Math.sqrt(deltaX * deltaX + deltaY * deltaY +
// deltaZ * deltaZ);
//
// if (riderSpeed > 5) {
// // 按照自己需求設置屏幕的亮度
// toggleBrightness(this);
// Log.e(TAG, brightness + ":::" +
// isAutoBrightness(this.getContentResolver()));
// Log.e("執行車友的拿手機的動作", riderSpeed + "");
// // pm.goToSleep(SystemClock.uptimeMillis());
// new Handler().postDelayed(new Runnable() {
//
// @Override
// public void run() {
//
// wake.release();
//
// }
// }, 50);// 在釋放的時候異常了
// }

下一篇: PLC、DCS、FCS三大控

上一篇: 電氣控制線路圖控制原

推薦產品

更多
中文字幕第二一区_久久久久在线视频_精品国产自在现线看久久_亚洲精品一区二区三区电影网

      9000px;">

          欧美性色综合网| 日韩一区二区免费高清| 精品久久久久香蕉网| 精品一区二区免费在线观看| 久久免费电影网| 日韩欧美的一区二区| 在线免费观看日本欧美| 9i在线看片成人免费| 国产一区二区看久久| 日本女人一区二区三区| 五月天欧美精品| 亚洲成人激情自拍| 欧美aⅴ一区二区三区视频| 亚洲成人精品一区二区| 午夜视频在线观看一区| 青青草国产精品97视觉盛宴| 日韩av高清在线观看| 精品在线你懂的| 99精品久久只有精品| 欧美一级高清大全免费观看| 久久久综合精品| 国产精品久久久久天堂| 亚洲精品成人在线| 久久99深爱久久99精品| 91国偷自产一区二区使用方法| 欧美一区二区福利视频| 国产精品国产三级国产普通话三级 | 亚洲三级在线免费| 亚洲成a人片在线不卡一二三区| 美女视频网站久久| 91国偷自产一区二区三区观看| 久久久精品tv| 久久 天天综合| 欧美日韩国产片| 亚洲欧洲日本在线| 国产福利电影一区二区三区| 日韩一区二区不卡| 久久精品国产一区二区| 91精品国产综合久久香蕉麻豆 | 亚洲欧洲美洲综合色网| 久久99国产精品免费| 欧美中文字幕不卡| 亚洲欧美日韩国产中文在线| 丁香婷婷深情五月亚洲| 国产精品系列在线| 99久久久精品免费观看国产蜜| 久久久久国产一区二区三区四区| 九九精品一区二区| 中文在线资源观看网站视频免费不卡| 久久99国产精品麻豆| 欧美一级黄色大片| 成人中文字幕在线| 久久亚洲精品国产精品紫薇 | 国产精品家庭影院| 成人av免费在线播放| 亚洲精品精品亚洲| 色综合视频在线观看| 亚洲国产欧美日韩另类综合| 91久久精品一区二区| 日本中文字幕一区| 国产性天天综合网| 欧美日韩精品一区二区三区| 日韩av一区二区三区| 久久久久久久久久看片| 在线观看不卡一区| 丁香啪啪综合成人亚洲小说| 亚洲最大的成人av| 久久久99精品免费观看不卡| 一本一道波多野结衣一区二区| 免费欧美高清视频| 亚洲欧美一区二区三区孕妇| 日本韩国精品在线| 91在线国产观看| www.亚洲免费av| 国产99久久久国产精品| 亚洲成人免费在线观看| 亚洲精品国产无天堂网2021| 国产女同性恋一区二区| 久久久久久**毛片大全| 日韩精品一区二区三区四区 | 欧美三电影在线| 91精品1区2区| 播五月开心婷婷综合| 久久精品国产澳门| 蜜臀av国产精品久久久久| 亚洲成年人网站在线观看| 亚洲成人午夜影院| 免费欧美日韩国产三级电影| 亚洲国产aⅴ成人精品无吗| 亚洲成人av免费| 久久国产综合精品| 国产成人精品影院| 99在线精品视频| 欧美体内she精高潮| 欧美大肚乱孕交hd孕妇| 国产精品久久久久久久久免费桃花 | 欧美xxxxx牲另类人与| 精品少妇一区二区三区在线播放| 在线成人av影院| 国产欧美日本一区视频| 亚洲电影一区二区三区| 久久aⅴ国产欧美74aaa| 在线免费不卡电影| 欧美mv日韩mv国产| 国产欧美视频一区二区| 日产精品久久久久久久性色| 国产91露脸合集magnet | 日韩美一区二区三区| 国产精品天天看| 国产一区二区久久| 日韩一区二区电影在线| 中文字幕亚洲一区二区av在线| 久久精品国产99久久6| 欧美亚洲丝袜传媒另类| 国产精品午夜电影| 成人午夜av影视| 欧美一区二区三区喷汁尤物| 亚洲素人一区二区| 国产成人综合在线观看| 国产欧美va欧美不卡在线| 麻豆精品视频在线| 91黄色免费版| 亚洲欧洲综合另类| 精品视频资源站| 免费人成精品欧美精品 | 欧美精品一区男女天堂| 日韩中文字幕一区二区三区| 91在线免费播放| 日韩电影免费一区| 精品成人在线观看| 国产福利一区二区| 亚洲女同女同女同女同女同69| 国产麻豆精品久久一二三| www亚洲一区| 欧美中文字幕一区二区三区亚洲| 午夜视频在线观看一区| 精品久久久久一区二区国产| 99久久综合狠狠综合久久| 日韩va欧美va亚洲va久久| 精品捆绑美女sm三区| 亚洲人成小说网站色在线| 欧美日韩国产乱码电影| 国产一区二区在线影院| 亚洲综合免费观看高清在线观看| 欧美在线播放高清精品| 成人免费毛片片v| 麻豆视频观看网址久久| 一区二区久久久久久| 国产亚洲一区二区三区| 91精品国产色综合久久不卡蜜臀 | 国产欧美日韩麻豆91| 精品国产免费视频| 日韩免费成人网| 欧美电影免费观看高清完整版| 欧美喷潮久久久xxxxx| 欧美色精品天天在线观看视频| 不卡的电影网站| a级高清视频欧美日韩| 丁香婷婷综合五月| 91视频在线观看| 成人免费毛片app| 色诱亚洲精品久久久久久| 欧美在线观看视频一区二区| 欧美午夜寂寞影院| 91精品国产综合久久久久久| 欧美亚洲自拍偷拍| 欧美精品18+| 欧美电视剧免费全集观看| 2021国产精品久久精品| 国产精品视频看| 午夜精品一区二区三区电影天堂| 夜夜爽夜夜爽精品视频| 国产精品88av| 99久久精品免费看| 91精品啪在线观看国产60岁| 国产午夜精品在线观看| 中文字幕视频一区| 亚洲色图在线播放| 亚洲另类在线制服丝袜| 亚洲欧美日韩国产中文在线| 一区二区激情小说| 国产日韩精品视频一区| 国产精品久久久久久久久免费樱桃| 成人美女视频在线观看| 欧美一区二区三区免费视频| yourporn久久国产精品| 欧美一区二区人人喊爽| 99久久精品免费| 99麻豆久久久国产精品免费| 欧美一区二区三区日韩视频| 精品嫩草影院久久| 午夜精品久久久久久不卡8050| 久久精品国产一区二区三| 国产一区二区三区免费| 最新久久zyz资源站| 欧美午夜在线观看| 国产精品电影一区二区| 粉嫩aⅴ一区二区三区四区| 成人免费视频网站在线观看| 中文字幕精品综合|