Android-關于傳感器你需要知道的

最近在搞一個自己的App,突發(fā)一個想法,給App加一個搖一搖隨機查看圖片的功能,這樣可以使得用戶在使用App的時候有更多的樂趣。實現搖一搖肯定少不了傳感器,在使用之余,索性總結一下在Android中關于傳感器的使用。

本文目錄:
1.什么是傳感器
2.常用傳感器介紹與用法
3.實現圖片搖一搖

1.什么是傳感器

維基百科是這樣定義的:傳感器是一種物理裝置或生物器官,能夠探測、感受外界的信號、物理條件(如光、熱、濕度)或化學組成(如煙霧),并將探知的信息傳遞給其他裝置或器官。

在Android中傳感器可以展示當前手機狀態(tài)的應用,包括硬件信息、當前位置、加速計、陀螺儀、光感、磁場、定向、電池窗臺,聲壓,同時還可以進行多點觸控的測試。只要你的想象力足夠豐富,完全可以利用這些信息做出一些很新奇得應用。

2.常用傳感器介紹與用法

Android平臺支持三個大類的傳感器

  • Motion sensors(運動傳感器)
    這些傳感器測量加速力,并沿三個軸的旋轉力。此類別包括加速度計,重力感應器, 陀螺儀和旋轉矢量傳感器。
  • Environmental sensors (環(huán)境傳感器)
    這些傳感器測量各種環(huán)境參數,例如環(huán)境空氣溫度和壓力,照明和濕度。此類別包括氣壓計,光度計,和溫度計。
  • Position sensors (位置傳感器)
    這些傳感器測量設備的物理位置。這個類別包括方向傳感器和磁力計。

好。下面來看看Android中怎么去使用傳感器。

第一步:得到SensorManager

SensorManager mSensorManager = (SensorManager) mContext
                .getSystemService(Context.SENSOR_SERVICE);

第二步:注冊傳感器

 Sensor sensor = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (null != sensor)
            mSensorManager.registerListener(this, sensor,
                    SensorManager.SENSOR_DELAY_NORMAL);

嗯。然后就可以監(jiān)聽傳感器數據的變化了。

我相信第一步大家都能看懂,這里主要說一下第二步。

registerListener這個方法有三個參數。

  • 第一個參數是傳感器數據變化的監(jiān)聽器
    我們需要去實現SensorEventListener接口,他里面有兩個回調方法
 @Override
    public void onSensorChanged(SensorEvent event) {
     //當傳感器的數值發(fā)生變化時調用
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
     //傳感器的精度發(fā)生變化時調用
    }
  • 第二個參數是我們需要監(jiān)聽的傳感器
    我們得到傳感器用的是下面這種方法:
 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

TYPE_ACCELEROMETER代表的就是加速度傳感器。Android定義了很多的常量來代表支持的傳感器,我們來看看Android平臺支持的傳感器類型。

  • 加速度傳感器:TYPE_ACCELEROMETER
    以m/s2測量它設備所有三個物理軸線方向(x,y,和z)加速度。
  • 周圍溫度傳感器:TYPE_AMBIENT_TEMPERATURE
    檢測周圍空氣溫度。
  • 重力傳感器:TYPE_GRAVITY
    測量重力
  • 陀螺儀傳感器:TYPE_GYROSCOPE
    以rad/s測量設備三個物理軸線方向(x,y,和z)。旋轉速度。
  • 光照傳感器:TYPE_LIGHT
    以lx測量周圍的光線級別。
  • 線性加速度傳感器:TYPE_LINEAR_ACCELERATION
    檢測沿著一個軸向的加速度。
  • 磁力傳感器:TYPE_MAGNETIC_FIELD
    測量周圍的三個物理軸線方向的磁場。
  • 方向傳感器: TYPE_ORIENTATION
    測量設備所有三個物理軸線方向(x,y和x)的旋轉角度。
  • 壓力傳感器:TYPE_PRESSURE
    測量周圍空氣氣壓
  • 接近傳感器:TYPE_PROXIMITY
    檢測物體與手機的距離
  • 相對濕度傳感器:TYPE_RELATIVE_HUMIDITY
    檢測周圍空氣相對濕度
  • 旋轉矢量傳感器:TYPE_ROTATION_VECTOR
    用于檢測運動和檢測旋轉。
  • 溫度傳感器: TYPE_TEMPERATURE
    檢測設備的溫度

下面再來看看傳感器的平臺的可用性

來源于官網

注意到圖中Yes右上角有個上標:1這個類型的傳感器在Android1.5(API Level 3)被添加,但是直到Android2.3(API Level 9)也不可用。 2這個傳感器是可用的,但是它被棄用。

  • 第三個參數是傳感器數據更新數據的速度
    有以下四個值可選,他們的速度是遞增的
  • SENSOR_DELAY_UI
  • SENSOR_DELAY_NORMAL
  • SENSOR_DELAY_GAME
  • SENSOR_DELAY_FASTEST

傳感器的基本使用和介紹截差不多就這些,下面來看看,怎么去實現一個圖片搖一搖的功能。

3.實現圖片搖一搖

要實現搖一搖,主要就是去監(jiān)聽手機加速度的變化,當達到一個值的時候就出發(fā)搖一搖這個事件。

說到這,你肯定就知道我們要用的就是加速度傳感器去實現這個功能。

先來看看效果圖:

廢話不多說了,下面直接上代碼,經過前面的知識儲備,我相信你肯定能看懂的

/**
 * Created by _SOLID
 * Date:2016/6/3
 * Time:9:55
 */
public class ShakePictureUtils implements SensorEventListener {

    // 兩次檢測的時間間隔
    private static final int UPTATE_INTERVAL_TIME = 100;
    // 加速度變化閾值,當搖晃速度達到這值后產生作用
    private static final int SPEED_THRESHOLD = 2000;

    private Context mContext;
    private SensorManager mSensorManager = null;
    private Vibrator mVibrator = null;
    private PictureDialog mPictureDialog = null;


    public ShakePictureUtils(Context context) {
        mContext = context;
        mSensorManager = (SensorManager) mContext
                .getSystemService(Context.SENSOR_SERVICE);
        mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
        mPictureDialog = new PictureDialog(mContext, R.style.PictureDialog);
        mPictureDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                registerSensor();
            }
        });
    }


    private long lastUpdateTime;
    private float lastX;
    private float lastY;
    private float lastZ;

    @Override
    public void onSensorChanged(SensorEvent event) {
        long currentUpdateTime = System.currentTimeMillis();

        long timeInterval = currentUpdateTime - lastUpdateTime;

        if (timeInterval < UPTATE_INTERVAL_TIME) {
            return;
        }

        lastUpdateTime = currentUpdateTime;
        float[] values = event.values;

        // 獲得x,y,z加速度
        float x = values[0];
        float y = values[1];
        float z = values[2];

        // 獲得x,y,z加速度的變化值
        float deltaX = x - lastX;
        float deltaY = y - lastY;
        float deltaZ = z - lastZ;

        // 將現在的坐標變成last坐標
        lastX = x;
        lastY = y;
        lastZ = z;


        Logger.i("values[0] = " + values[0]);
        Logger.i("values[1] = " + values[1]);
        Logger.i("values[2] = " + values[2]);

        double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ
                * deltaZ)
                / timeInterval * 10000;
        Logger.i("speed:" + speed);
        if (speed > SPEED_THRESHOLD) {
            //在這里可以提供一個回調
            mVibrator.vibrate(300);
            requestPicture();
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    public void registerSensor() {
        Sensor sensor = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (null != sensor)
            mSensorManager.registerListener(this, sensor,
                    SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void unRegisterSensor() {

        lastX = 0;
        lastY = 0;
        lastZ = 0;
        mSensorManager.unregisterListener(this);
    }


    private void requestPicture() {
        HttpClientManager.getData(Apis.Urls.RandomPicture, new JsonHttpCallBack<RandomPictureBean>() {
            @Override
            public void onStart() {
                unRegisterSensor();
                ToastUtils.getInstance().showToast("圖片獲取中...");
            }

            @Override
            public void onSuccess(RandomPictureBean result) {
                mPictureDialog.setPicture(result.getP_ori());
            }

            @Override
            public void onError(Exception e) {
                registerSensor();
            }
        });
    }
}


我是講=將搖一搖這個功能做了一下封裝,方便以后的使用。代碼的實現思想就是去判斷三個坐標軸加速度的變化值,當其達到一個閾值的時候則觸發(fā)搖一搖。
最后來看看在Activity中怎么去使用

  1. 在onCreate方法中去初始化搖一搖
ShakePictureUtils mShakePictureUtils = new ShakePictureUtils(this);
  1. 在onResume方法中去注冊
    @Override
    protected void onResume() {
        super.onResume();
        mShakePictureUtils.registerSensor();
    }
  1. 在onPause方法中去解注冊
    @Override
    protected void onPause() {
        super.onPause();
        mShakePictureUtils.unRegisterSensor();
    }

源碼地址:ShakePictureUtils

也請大家也關注下我的一個開源項目GanHuoIO。這是基于gank.io提供的api寫的一個Android客戶端,謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,716評論 25 709
  • Android傳感器定義 Android 傳感器相關術語微機電傳感器(MEMS)MEMS 通常制作在規(guī)格很小的硅芯...
    Jannonx閱讀 4,704評論 0 1
  • 傳感器 傳感器Sensor是一種檢測裝置,能感受到被測量的信息,并能將感受到的信息,按一定規(guī)律變換成為電信號或其他...
    Reathin閱讀 6,579評論 0 5
  • 在我們這個層次,如果稍往外探究,我們總是氤氳在功利的人文文化氛圍中。以前我總以為是學校教育的責任,但追根溯源或來自...
    江蘇劉志祥閱讀 363評論 0 0
  • 平臺有多重要?開始簡書寫作之前,我只是從戰(zhàn)隼老師那里看一些時間管理和知識管理的文章,不明覺厲的感覺。讀書呢,就是上...
    楷楷媽頻道閱讀 1,705評論 6 11

友情鏈接更多精彩內容