1. 程式人生 > >android拾遺05——搖一搖開發

android拾遺05——搖一搖開發

android的搖一搖是基於android的加速度感測器開發實現的,主要使用到了以下類和介面:

  1. SensorManager 感測器管理器,可以為感測器註冊監聽器
  2. SensorEventListener 監聽感測器的動作,在回撥函式裡響應

使用到了這幾個方法:

1.getSystemService(String serviceName) 使用這個方法例項化感測器管理器 這個方法是Activity的
2.registerListener(SensorEventListener listener,Sensor sensor,int samplingPeriodUs)

官網關於這個方法的解釋:

public boolean registerListener (SensorEventListener listener, Sensor sensor, int samplingPeriodUs)

Added in API level 3
Registers a SensorEventListener for the given sensor at the given sampling frequency.

The events will be delivered to the provided SensorEventListener as soon as they are available. To reduce the power consumption, applications can use registerListener(SensorEventListener, Sensor, int, int) instead and specify a positive non-zero maximum reporting latency.

In the case of non-wake-up sensors, the events are only delivered while the Application Processor (AP) is not in suspend mode. See isWakeUpSensor() for more details. To ensure delivery of events from non-wake-up sensors even when the screen is OFF, the application registering to the sensor must hold a partial wake-lock to keep the AP awake, otherwise some events might be lost while the AP is asleep. Note that although events might be lost while the AP is asleep, the sensor will still consume power if it is not explicitly deactivated by the application. Applications must unregister their SensorEventListeners in their activity’s onPause() method to avoid consuming power while the device is inactive. See registerListener(SensorEventListener, Sensor, int, int) for more details on hardware FIFO (queueing) capabilities and when some sensor events might be lost.

In the case of wake-up sensors, each event generated by the sensor will cause the AP to wake-up, ensuring that each event can be delivered. Because of this, registering to a wake-up sensor has very significant power implications. Call isWakeUpSensor() to check whether a sensor is a wake-up sensor. See registerListener(SensorEventListener, Sensor, int, int) for information on how to reduce the power impact of registering to wake-up sensors.

Note: Don’t use this method with one-shot trigger sensors such as TYPE_SIGNIFICANT_MOTION. Use requestTriggerSensor(TriggerEventListener, Sensor) instead. Use getReportingMode() to obtain the reporting mode of a given sensor.

Parameters
listener A SensorEventListener object.
sensor The Sensor to register to.
samplingPeriodUs The rate sensor events are delivered at. This is only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster. The value must be one of SENSOR_DELAY_NORMAL, SENSOR_DELAY_UI, SENSOR_DELAY_GAME, or SENSOR_DELAY_FASTEST or, the desired delay between events in microseconds. Specifying the delay in microseconds only works from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of the SENSOR_DELAY_* constants.
Returns
true if the sensor is supported and successfully enabled.
See Also
registerListener(SensorEventListener, Sensor, int, Handler)
unregisterListener(SensorEventListener)
unregisterListener(SensorEventListener, Sensor)

我的解釋

方法作用

這個方法會為系統的感測器繫結一個監聽器,不同的監聽器需要傳入不同的引數進行控制,

引數解釋

listener
一個事件監聽器,這個引數需要自己實現SensorEventListener ,要實現OnSensorChanged(SensorEvent event) 這是回撥的方法,當感測器的值改變的時候就被呼叫(比如搖手機)

Sensor
這個是被監聽的感測器,可以使用getDefaultSensor(int SensorType) 根據type值的不同可以設定不同的感測器,
主要有:
加速度感測器:Sensor.TYPE_ACCELEROMETER
方向感測器:Sensor.TYPE_ORIENTATION
磁場感測器:Sensor.TYPE_MAGNETIC_FIELD
溫度感測器:Sensor.TYPE_TEMPERATURE
光感測器:Sensor.TYPE_LIGHT
壓力感測器:Sensor.TYPE_PRESSURE(指示當地大氣壓力)

不是所有的手機都帶有這些感測器,有的沒有

samplingPeriodUs

這個引數指定感測器獲取資料的頻率,有以下幾個值:
SensorManager.SENSOR_DELAY_FASTEST
最快,耗電最大,感測器需求高的才用
SensorManager.SENSOR_DELAY_GAME
適合遊戲的,一般使用這個就能達到實時的要求
SensorManager.SENSOR_DELAY_NORMAL
一般的,實時要求不高的時候才用
SensorManager.SENSOR_DELAY_UI
最慢,延遲最大

接下來的程式碼通過監測手機的加速度來判斷手機是否被晃動,當xyz任意一個方向的加速度的值超過四十,就認為被晃動了

package com.exe.liuchenfei.yaoyiyao;

import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Vibrator;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity implements SensorEventListener {

    //感測器管理器
    SensorManager sensorManager;
    //震動器
    Vibrator vibrator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
    }

    @Override
    protected void onStop() {
        //取消註冊監聽器
        sensorManager.unregisterListener(this);
        super.onStop();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //為系統的加速度感測器註冊監聽器
        sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onSensorChanged(SensorEvent event)
    {
        float values[]=event.values;
        //獲取x方向的加速度
        float xa=values[0];
        //獲取y方向上的速度
        float ya=values[1];
        //獲取z方向上的速度
        //x方向沿螢幕向左,y沿螢幕向上,z垂直螢幕向裡
        float za=values[2];
        //當檢測到某一方向加速度大於40時認為晃動了手機
        if (Math.abs(xa)>40||Math.abs(ya)>40||Math.abs(za)>40)
        {
            vibrator.vibrate(500);
            Toast.makeText(this,"晃動了手機",Toast.LENGTH_SHORT).show();
        }
    }

    //感測器精度變化時回撥的方法
    @Override
    public void onAccuracyChanged(Sensor sensor,int accuracy)
    {

    }
}