Android传感器——传感器监听器及摇一摇案例

接上<Android传感器——获取本机传感器>

https://blog.csdn.net/nishigesb123/article/details/90143498

 

部分参考:https://developer.android.google.cn/guide/topics/sensors/sensors_overview.html


传感器监听器(Monitoring Sensor Events)

o monitor raw sensor data you need to implement two callback methods that are exposed through the SensorEventListener interface: onAccuracyChanged() and onSensorChanged(). The Android system calls these methods whenever the following occurs:

The following code shows how to use the onSensorChanged() method to monitor data from the light sensor. This example displays the raw sensor data in a TextView that is defined in the main.xml file as sensor_data.

若要监视原始传感器数据,需要实现两个回调方法,这些回调方法通过SensorEventListener接口:onAccuracyChanged()onSensorChanged()。每当发生以下情况时,Android系统都会调用这些方法:

 下面的代码演示如何使用onSensorChanged()方法监视来自光传感器的数据。此示例将原始传感器数据显示在TextView在main.xml文件中定义为sensor_data.

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor mLight;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        float lux = event.values[0];
        // Do something with this sensor value.
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

In this example, the default data delay (SENSOR_DELAY_NORMAL) is specified when the registerListener()method is invoked. The data delay (or sampling rate) controls the interval at which sensor events are sent to your application via the onSensorChanged() callback method. The default data delay is suitable for monitoring typical screen orientation changes and uses a delay of 200,000 microseconds. You can specify other data delays, such as SENSOR_DELAY_GAME (20,000 microsecond delay), SENSOR_DELAY_UI (60,000 microsecond delay), or SENSOR_DELAY_FASTEST (0 microsecond delay). As of Android 3.0 (API Level 11) you can also specify the delay as an absolute value (in microseconds).

The delay that you specify is only a suggested delay. The Android system and other applications can alter this delay. As a best practice, you should specify the largest delay that you can because the system typically uses a smaller delay than the one you specify (that is, you should choose the slowest sampling rate that still meets the needs of your application). Using a larger delay imposes a lower load on the processor and therefore uses less power.

There is no public method for determining the rate at which the sensor framework is sending sensor events to your application; however, you can use the timestamps that are associated with each sensor event to calculate the sampling rate over several events. You should not have to change the sampling rate (delay) once you set it. If for some reason you do need to change the delay, you will have to unregister and reregister the sensor listener.

It's also important to note that this example uses the onResume() and onPause() callback methods to register and unregister the sensor event listener. As a best practice you should always disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours because some sensors have substantial power requirements and can use up battery power quickly. The system will not disable sensors automatically when the screen turns off

补充说明

注册传感器监听器的所需要的三个参数(部分)

  • 监听回调接口
  • 传感器
  • 传感器数据的速度值

对?传感器数据的速度值这个参数常见又有如下几种可供选择

  • SENSOR_ DELAY _GAME:(20000微秒)如果利用传感器开发游戏, 建议使用该值。 一般大多数实时行较高的游戏使用该级别。
  • SENSOR_ DELAY NORMAL: (200000微秒)默认的获取传感器数据的速度,标准延迟,对于一般的益智类游戏或者EASY界别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧的现象。
  • SENSOR DELAY_ UI:(60000微秒) 若使用传感器更新UI,建议使用该值。
  • SENSOR DELAY _FASTEST:(0微秒延迟) 最低延迟,一般不是特别灵敏的处理不推荐使用,该模式可能造成手机电量大量消耗,而且由于传递的为大量的原始数据,算法处理不好将会影响游戏逻辑和U的性能。
        //注册传感器的监听器
        sm.registerListener(new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                //传感器数据变化,在该方中我们可以获取传感器变化的值
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //传感器精度变化
            }
        },type_accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
    }

另外,回调接口中传感器经度的变化可供参考如下:

传感器精度的变化精度通过四个状态常量代表

  • SENSOR_STATUS_ACCURAY_LoW:低
  • SENSOR STATUS ACCURACY MEDIUM:中
  • SENSOR_STATUS ACCURACYHIGH:高
  • SENSOR STATUS UNRELIABLE:不可靠

传感器坐标系

通常,传感器框架使用一个标准的3维坐标系来表达数据值。对于大多数传感器, 当设备放置默认的方向(看下图) 的时候,坐标系被定义和设备的屏幕相关。当设备放置为它默认的方向,X轴是水平并指向右边,Y轴是竖直并指向上方,并且Z轴指向屏幕面的外侧。在这个系统,坐标系统有负的2值。

这个坐标系被用于下面的传感器:

  • 加速度传感器 (Acceleration sensor)
  • 重力传感器(Gravity sensor)
  • 陀螺仪传感器 (Gyroscope)
  • 线性加速度传感器 (Linear acceleration sensor)
  • 磁场传 感器(Geomagnetic field sensor)

许多传感器的传感器事件值在相对于设备静止的特定坐标系中表示。

监听小案例

准备一个TextView用于显示数据

package com.example.sensor;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.content);
        //获取系统传感器管理器
        SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        //通过系统传感器管理器..获取本机所有传感器.
        List<Sensor> sensorList = sm.getSensorList(Sensor.TYPE_ALL);

        for(Sensor s :sensorList){
            Log.i("sensorList",s.toString());
        }
        //获取指定的某一个传感器,下面为加速度传感器
        Sensor type_accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if(type_accelerometer!=null){
            Log.i("type_accelerometer",type_accelerometer.toString());
        }
        //注册传感器的监听器
        sm.registerListener(new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                //传感器数据变化,在该方中我们可以获取传感器变化的值
                float x=event.values[0];
                float y=event.values[1];
                float z=event.values[2];
                textView.setText("x="+x+"y="+y+"z="+z);
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //传感器精度变化
            }
        },type_accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
    }
}

效果如下: 模拟器上可能看不出啥效果,真机上速度会实时变化(根据加速度)

摇一摇案例

使用加速度传感器~

直接在?的案例基础上修改

再准备一个TextView提示开始(其实可有可无)

package com.example.sensor;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    private TextView textView_start;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.content);
        textView_start = findViewById(R.id.textView_start);
        //获取系统传感器管理器
        SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        //通过系统传感器管理器..获取本机所有传感器.
        List<Sensor> sensorList = sm.getSensorList(Sensor.TYPE_ALL);

        for (Sensor s : sensorList) {
            Log.i("sensorList", s.toString());
        }
        //获取指定的某一个传感器,下面为加速度传感器
        Sensor type_accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (type_accelerometer != null) {
            Log.i("type_accelerometer", type_accelerometer.toString());
        }
        //注册传感器的监听器
        sm.registerListener(new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                //传感器数据变化,在该方中我们可以获取传感器变化的值
                float x = event.values[0];
                float y = event.values[1];
                float z = event.values[2];
                textView.setText("x=" + x + "y=" + y + "z=" + z);
                //  System.out.println("x="+x+",y="+y+",z="+z);
                if ((Math.abs(x) + Math.abs(y) + Math.abs(z)) >= ringValue && flag == false) {
                    flag = true;
                    textView_start.setVisibility(View.VISIBLE);
                    MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.test);
                    mp.start();
                    mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                        @Override
                        public void onCompletion(MediaPlayer mp) {
                            mp.release();
                            flag = false;
                            textView_start.setVisibility(View.GONE);
                        }
                    });
                }
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //传感器精度变化
            }
        }, type_accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    int ringValue = 40;//三维XYZ三个值的总和达到这个值表示为摇晃
    boolean flag = false;//表示是否已经在播放声音
}

效果如下: 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云无心鸟知还

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值