日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android传感器编程入门

發布時間:2023/12/13 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android传感器编程入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言

我很喜歡電腦,可是筆記本還是太大,筆記本電腦再小還是要弄個小包背起來的,智能手機則不同,它完全就是一個手機,可以隨意裝在一個口袋里隨身攜帶。因此我在2002年左右時最喜歡玩裝備是Dell的PDA,2007年的時候最喜歡玩的是N73,而在2010年最喜歡玩的則是Milestone。眼見著手機的功能越來越強,時至今日智能手機甚至在某些方面已經強過了臺式機和筆記本。本節課講的就是智能手機強過臺式機和筆記本的地方:傳感器。

2008年的時候我很喜歡我的小白筆記本Macbook,喜歡玩它的一個小軟件,一拍桌子,筆記本感受到了震動,它就轉換了一個桌面出來,這讓我像個小孩子一樣沒事就拍拍桌子。這一功能這得益于蘋果筆記本內置有傳感器。

我不知道iPhone手機是不是第一個把各種各樣的傳感器運用在手機上的,不過我知道iPhone是把傳感器運用在手機上最成功的第一個。隨后的Android系統也內置了大量的傳感器,這讓Android系統手機和普通的諾基亞智能機和Windows CE智能機相比牛氣了許多,在擁有了Milestone之后,我的N73就被仍在抽屜的角落里了。

從Android1.5開始,系統內置了對多達八種傳感器的支持,他們分別是:加速度傳感器(accelerometer),陀螺儀(gyroscope),環境光照傳感器(light),磁力傳感器(magnetic field),方向傳感器(orientation),壓力傳感器(pressure),距離傳感器(proximity)和溫度傳感器(temperature)。

利用這些傳感器我們可以制作出各種有趣的應用程序和游戲。譬如在口袋里晃一晃手機,手機就開始神不知鬼不覺的錄音,不要著急這個很容易做,我們在本文的結尾就一起制作這個小應用。

本講的學習方式還是在實戰中學習,需要提醒的是模擬器中無法模擬傳感器,因此你需要準備一款Android真機才能運行本講的例子。

二、實例:手機傳感器清單

我們還是先看程序后解釋,

1、創建一個項目 Lesson37_HelloSensor , 主Activity名字叫 mainActivity.java

2、UI布局文件main.xml的內容如下:

1<?xml version="1.0"?encoding="utf-8"?>
2<linearlayout android:layout_height="fill_parent"android:layout_width="fill_parent"?android:orientation="vertical"xmlns:android="/apk/res/android">
3<textview android:layout_height="wrap_content"android:layout_width="fill_parent"?android:text=""android:id="@+id/TextView01">
4</textview></linearlayout>

3、mainActivity.java的內容如下:

01package?basic.android.lesson37;
02?
03import?java.util.List;
04?
05import?android.app.Activity;
06import?android.content.Context;
07import?android.hardware.Sensor;
08import?android.hardware.SensorManager;
09import?android.os.Bundle;
10import?android.widget.TextView;
11?
12public?class?MainActivity?extends?Activity {
13?
14????/** Called when the activity is first created. */
15????@Override
16????public?void?onCreate(Bundle savedInstanceState) {
17????????super.onCreate(savedInstanceState);
18????????setContentView(R.layout.main);
19?
20????????//準備顯示信息的UI組建
21????????final?TextView tx1 = (TextView) findViewById(R.id.TextView01);
22?
23????????//從系統服務中獲得傳感器管理器
24????????SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
25?
26????????//從傳感器管理器中獲得全部的傳感器列表
27????????List<sensor> allSensors = sm.getSensorList(Sensor.TYPE_ALL);
28?
29????????//顯示有多少個傳感器
30????????tx1.setText("經檢測該手機有"?+ allSensors.size() +?"個傳感器,他們分別是:\n");
31?
32????????//顯示每個傳感器的具體信息
33????????for?(Sensor s : allSensors) {
34?
35????????????String tempString =?"\n"?+?"? 設備名稱:"?+ s.getName() +?"\n"+?"? 設備版本:"?+ s.getVersion() +?"\n"?+?"? 供應商:"
36????????????????????+ s.getVendor() +?"\n";
37?
38????????????switch?(s.getType()) {
39????????????case?Sensor.TYPE_ACCELEROMETER:
40????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 加速度傳感器accelerometer"?+ tempString);
41????????????????break;
42????????????case?Sensor.TYPE_GYROSCOPE:
43????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 陀螺儀傳感器gyroscope"?+ tempString);
44????????????????break;
45????????????case?Sensor.TYPE_LIGHT:
46????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 環境光線傳感器light"?+ tempString);
47????????????????break;
48????????????case?Sensor.TYPE_MAGNETIC_FIELD:
49????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 電磁場傳感器magnetic field"?+ tempString);
50????????????????break;
51????????????case?Sensor.TYPE_ORIENTATION:
52????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 方向傳感器orientation"?+ tempString);
53????????????????break;
54????????????case?Sensor.TYPE_PRESSURE:
55????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 壓力傳感器pressure"?+ tempString);
56????????????????break;
57????????????case?Sensor.TYPE_PROXIMITY:
58????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 距離傳感器proximity"?+ tempString);
59????????????????break;
60????????????case?Sensor.TYPE_TEMPERATURE:
61????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 溫度傳感器temperature"?+ tempString);
62????????????????break;
63????????????default:
64????????????????tx1.setText(tx1.getText().toString() + s.getType() +?" 未知傳感器"?+ tempString);
65????????????????break;
66????????????}
67????????}
68?
69????}
70}</sensor>

4、連接真機Milestone,編譯并運行程序,顯示結果如下:

5、結合上面的程序我們做一些解釋。

  • Android所有的傳感器都歸傳感器管理器 SensorManager 管理,獲取傳感器管理器的方法很簡單:

    String service_name = Context.SENSOR_SERVICE;

    SensorManager sensorManager = (SensorManager)getSystemService(service_name);

  • 現階段Android支持的傳感器有8種,它們分別是:
    傳感器類型常量內部整數值中文名稱
    Sensor.TYPE_ACCELEROMETER1加速度傳感器
    Sensor.TYPE_MAGNETIC_FIELD2磁力傳感器
    Sensor.TYPE_ORIENTATION3方向傳感器
    Sensor.TYPE_GYROSCOPE4陀螺儀傳感器
    Sensor.TYPE_LIGHT5環境光照傳感器
    Sensor.TYPE_PRESSURE6壓力傳感器
    Sensor.TYPE_TEMPERATURE7溫度傳感器
    Sensor.TYPE_PROXIMITY8距離傳感器
  • 從傳感器管理器中獲取其中某個或者某些傳感器的方法有如下三種:

    第一種:獲取某種傳感器的默認傳感器

    Sensor defaultGyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

    第二種:獲取某種傳感器的列表

    List<Sensor> pressureSensors = sensorManager.getSensorList(Sensor.TYPE_PRESSURE);

    第三種:獲取所有傳感器的列表,我們這個例子就用的第三種

    List<Sensor> allSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

  • 對于某一個傳感器,它的一些具體信息的獲取方法可以見下表:
    方法描述
    getMaximumRange()最大取值范圍
    getName()設備名稱
    getPower()功率
    getResolution()精度
    getType()傳感器類型
    getVentor()設備供應商
    getVersion()設備版本號
  • 三、實例:窈窈錄音器

    通過上面的例子我們學會了如何獲得某種類型的傳感器,下面我通過一個實例來學會如何使用某一個類型的傳感器。我們這里使用加速度傳感器來實現這樣一個功能:開啟我們的錄音程序放在你的口袋或者提包里,需要錄音的時候把衣服整理一下,或者把提包挪動個位置,那么此時手機就會感受到變化從而開始錄音。由此達到神不知鬼不覺的錄音效果。說起來似乎有點神,其實做起來很簡單,讓我們開始吧。

    簡單的錄音程序已經在第28講的時候做過了,我們在28講程序的基礎上寫本講的代碼。

    1、新建一個項目 Lesson37_YYRecorder , 主文件叫 MainActivity.java ,具體信息都可以參見第二十八講的“窈窈錄音”的例子。

    2、這里只貼出于28講不同的 MainActivity.java? 的代碼,請注意看注釋:

    001package?basic.android.lesson37;
    002?
    003import?java.io.File;
    004import?java.io.IOException;
    005import?java.util.Calendar;
    006import?java.util.Locale;
    007?
    008import?android.app.Activity;
    009import?android.content.Context;
    010import?android.hardware.Sensor;
    011import?android.hardware.SensorEvent;
    012import?android.hardware.SensorEventListener;
    013import?android.hardware.SensorManager;
    014import?android.media.MediaRecorder;
    015import?android.os.Bundle;
    016import?android.text.format.DateFormat;
    017import?android.view.View;
    018import?android.widget.Button;
    019import?android.widget.TextView;
    020import?android.widget.Toast;
    021?
    022public?class?MainActivity?extends?Activity {
    023?
    024????//錄音和停止按鈕
    025????private?Button recordButton;
    026????private?Button stopButton;
    027?
    028????//檢測搖動相關變量
    029????private?long?initTime =?0;
    030????private?long?lastTime =?0;
    031????private?long?curTime =?0;
    032????private?long?duration =?0;
    033?
    034????private?float?last_x =?0.0f;
    035????private?float?last_y =?0.0f;
    036????private?float?last_z =?0.0f;
    037?
    038????private?float?shake =?0.0f;
    039????private?float?totalShake =?0.0f;
    040?
    041????//媒體錄音器對象
    042????private?MediaRecorder mr;
    043?
    044????//是否正在錄音
    045????private?boolean?isRecoding =?false;
    046?
    047????@Override
    048????public?void?onCreate(Bundle savedInstanceState) {
    049????????super.onCreate(savedInstanceState);
    050????????setContentView(R.layout.main);
    051?
    052????????// UI組件
    053????????recordButton = (Button)?this.findViewById(R.id.Button01);
    054????????stopButton = (Button)?this.findViewById(R.id.Button02);
    055????????final?TextView tx1 = (TextView)this.findViewById(R.id.TextView01);
    056?
    057????????// 錄音按鈕點擊事件
    058????????recordButton.setOnClickListener(new?View.OnClickListener() {
    059?
    060????????????@Override
    061????????????public?void?onClick(View v) {
    062????????????????//如果沒有在錄音,那么點擊按鈕可以開始錄音
    063????????????????if(!isRecoding){
    064????????????????????startRecord();
    065????????????????}
    066????????????}
    067????????});
    068?
    069????????// 停止按鈕點擊事件
    070????????stopButton.setOnClickListener(new?View.OnClickListener() {
    071?
    072????????????@Override
    073????????????public?void?onClick(View v) {
    074????????????????initShake();
    075????????????????//如果正在錄音,那么可以停止錄音
    076????????????????if?(mr !=?null) {
    077????????????????????mr.stop();
    078????????????????????mr.release();
    079????????????????????mr =?null;
    080????????????????????recordButton.setText("錄音");
    081????????????????????Toast.makeText(getApplicationContext(),?"錄音完畢", Toast.LENGTH_LONG).show();
    082????????????????????isRecoding =?false;
    083?
    084????????????????}
    085????????????}
    086????????});
    087?
    088????????// 獲取傳感器管理器
    089????????SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    090????????// 獲取加速度傳感器
    091????????Sensor acceleromererSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    092?
    093????????// 定義傳感器事件監聽器
    094????????SensorEventListener acceleromererListener =?newSensorEventListener() {
    095?
    096????????????@Override
    097????????????public?void?onAccuracyChanged(Sensor sensor,?int?accuracy) {
    098????????????????//什么也不干
    099????????????}
    100?
    101????????????//傳感器數據變動事件
    102????????????@Override
    103????????????public?void?onSensorChanged(SensorEvent event) {???
    104?
    105????????????????//如果沒有開始錄音的話可以監聽是否有搖動事件,如果有搖動事件可以開始錄音
    106????????????????if(!isRecoding){
    107????????????????????//獲取加速度傳感器的三個參數
    108????????????????????float?x = event.values[SensorManager.DATA_X];
    109????????????????????float?y = event.values[SensorManager.DATA_Y];
    110????????????????????float?z = event.values[SensorManager.DATA_Z];
    111?
    112????????????????????//獲取當前時刻的毫秒數
    113????????????????????curTime = System.currentTimeMillis();
    114?
    115????????????????????//100毫秒檢測一次
    116????????????????????if?((curTime - lastTime) >?100) {
    117?
    118????????????????????????duration = (curTime - lastTime);
    119?
    120????????????????????????// 看是不是剛開始晃動
    121????????????????????????if?(last_x ==?0.0f && last_y ==?0.0f && last_z ==0.0f) {
    122????????????????????????????//last_x、last_y、last_z同時為0時,表示剛剛開始記錄
    123????????????????????????????initTime = System.currentTimeMillis();
    124????????????????????????}?else?{
    125????????????????????????????// 單次晃動幅度
    126????????????????????????????shake = (Math.abs(x - last_x) + Math.abs(y - last_y) + Math.abs(z - last_z)) / duration *?100;
    127????????????????????????}
    128?
    129????????????????????????//把每次的晃動幅度相加,得到總體晃動幅度
    130????????????????????????totalShake += shake;
    131?
    132????????????????????????// 判斷是否為搖動,這是我自己寫的標準,不準確,只是用來做教學示例,別誤會了^_^
    133????????????????????????if?(totalShake >?10?&& totalShake / (curTime - initTime) *?1000?>?10) {
    134????????????????????????????startRecord();
    135????????????????????????????initShake();
    136????????????????????????}
    137?
    138????????????????????????tx1.setText("總體晃動幅度="+totalShake+?"\n平均晃動幅度="+totalShake / (curTime - initTime) *?1000?);
    139????????????????????}
    140?
    141????????????????????last_x = x;
    142????????????????????last_y = y;
    143????????????????????last_z = z;
    144????????????????????lastTime = curTime;
    145????????????????}
    146????????????}
    147?
    148????????};
    149?
    150????????//在傳感器管理器中注冊監聽器
    151????????sm.registerListener(acceleromererListener, acceleromererSensor, SensorManager.SENSOR_DELAY_NORMAL);
    152?
    153????}
    154?
    155????// 開始錄音
    156????public?void?startRecord() {
    157????????//把正在錄音的標志設為真
    158????????isRecoding =?true;
    159????????//存放文件
    160????????File file =?new?File("/sdcard/"?+?"YY"
    161????????????????+?new?DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) +?".amr");
    162?
    163????????Toast.makeText(getApplicationContext(),?"正在錄音,錄音文件在"?+ file.getAbsolutePath(), Toast.LENGTH_LONG).show();
    164?
    165????????// 創建錄音對象
    166????????mr =?new?MediaRecorder();
    167?
    168????????// 從麥克風源進行錄音
    169????????mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    170?
    171????????// 設置輸出格式
    172????????mr.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
    173?
    174????????// 設置編碼格式
    175????????mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    176?
    177????????// 設置輸出文件
    178????????mr.setOutputFile(file.getAbsolutePath());
    179?
    180????????try?{
    181????????????// 創建文件
    182????????????file.createNewFile();
    183????????????// 準備錄制
    184????????????mr.prepare();
    185????????}?catch?(IllegalStateException e) {
    186????????????e.printStackTrace();
    187????????}?catch?(IOException e) {
    188????????????e.printStackTrace();
    189????????}
    190????????// 開始錄制
    191????????mr.start();
    192????????recordButton.setText("錄音中……");
    193????}
    194?
    195????//搖動初始化
    196????public?void?initShake() {
    197????????lastTime =?0;
    198????????duration =?0;
    199????????curTime =?0;
    200????????initTime =?0;
    201????????last_x =?0.0f;
    202????????last_y =?0.0f;
    203????????last_z =?0.0f;
    204????????shake =?0.0f;
    205????????totalShake =?0.0f;
    206????}
    207}

    3、連接真機Milestone,編譯并運行程序:

    晃動機器,開始錄音

    查看錄音文件,效果還可以:

    4、我們小結一下:

    到Android2.2版本為止,系統并沒有給開發者提供多少可用的包裝好的傳感器信息,只是提供了傳感器發出的原始數據,這些原始數據存放在? event.values 的數組里,開發人員需要從這些裸數據總自行發掘有用的信息,譬如從加速度傳感器的3維裸數據中獲得搖動的判斷(我的搖動判斷很弱智,有時間再改吧……)。

    好了本講就先到這里,關于傳感器有機會我們展開再談,下次再見吧。

    轉載于:https://www.cnblogs.com/java-time/archive/2011/05/25/tt150.html

    總結

    以上是生活随笔為你收集整理的Android传感器编程入门的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。