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;//表示是否已经在播放声音
}

效果如下: 

全部评论

相关推荐

01-30 22:03
门头沟学院 Java
用微笑面对困难:我滴妈,【俩月】【实习】【主管】仨debuff吃满了,独立设计开发的项目写了绝大占比的运营板块,你独立开发,那维护、问题复盘、日志更新、bug、策划书全是自己整的? 不建议写那么大,可以从小出发更容易
点赞 评论 收藏
分享
01-28 16:12
中南大学 Java
几年前还没有chatgpt的时候,刷题真的是很痛苦。刷不出来只能看题解,题解有几个问题:第一个是每次看的写题解的人都不一样,很难有一个统一的思路;第二个也是最重要的是,题解只提供了作者自己的思路,但是没有办法告诉你你的思路哪里错了。其实很少有错误的思路,我只是需要被引导到正确的思路上面去。所以传统题解学习起来非常困难,每次做不出来难受,找题解更难受。但是现在chatgpt能做很多!它可以这样帮助你&nbsp;-1.&nbsp;可以直接按照你喜欢的语言生成各种解法的题解和分析复杂度。2.&nbsp;把题和你写的代码都发给它,它可以告诉你&nbsp;你的思路到底哪里有问题。有时候我发现我和题解非常接近,只是有一点点🤏想错了。只要改这一点点就是最优解。信心倍增。3.&nbsp;如果遇到不懂的题解可以一行一行询问为什么要这样写,chatgpt不会嫌你烦。有时候我觉得自己的range写错了,其实那样写也没错,只是chat老师的题解有一点优化,这个它都会讲清楚。4.&nbsp;它可以帮你找可以用同类型解法来做的题。然后它可以保持解法思路不变,用一个思路爽刷一个类型的题。如果题目之间思路又有变化,它会告诉你只有哪里变了,其他的地方还是老思路。5.&nbsp;它也可以直接帮你总结模板,易错点。经过chat老师的指导,我最大的改变是敢刷题了。之前刷题需要先找某一个人写的算法题repo,然后跟着某一个人他的思路刷他给的几个题。如果想写别的题,套用思路失败了,没有他的题解,也不知道到底哪里错了;看别人的题解,思路又乱了。这个问题在二分查找和dp类型的题里面特别常见。但是现在有chat老师,他会针对我的代码告诉我我哪里想错了,应该怎么做;还按照我写代码的习惯帮我总结了一套属于我的刷题模板。每天写题全是正反馈!
明天不下雨了:那我建议可以用 chatgpt atlas 或者 dia 去刷,也可以用 chrome 加个 ai 插件去刷 左边刷题右边 chat 效果很好
AI时代的工作 VS 传...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务