最近在搞一個自己的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中怎么去使用
- 在onCreate方法中去初始化搖一搖
ShakePictureUtils mShakePictureUtils = new ShakePictureUtils(this);
- 在onResume方法中去注冊
@Override
protected void onResume() {
super.onResume();
mShakePictureUtils.registerSensor();
}
- 在onPause方法中去解注冊
@Override
protected void onPause() {
super.onPause();
mShakePictureUtils.unRegisterSensor();
}
源碼地址:ShakePictureUtils
也請大家也關注下我的一個開源項目GanHuoIO。這是基于gank.io提供的api寫的一個Android客戶端,謝謝。