美文网首页
Android 传感器

Android 传感器

作者: gaookey | 来源:发表于2022-07-14 12:49 被阅读0次
image.png
加速传感器
public class MainActivity extends AppCompatActivity implements SensorEventListener {
    // 定义系统的Sensor管理器
    private SensorManager sensorManager;
    private TextView etTxt1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取程序界面上的文本框组件
        etTxt1 = findViewById(R.id.txt1);
        // 获取系统的传感器管理服务
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  // ①
    }

    @Override
    public void onResume() {
        super.onResume();
         
        /*
         * 为系统的加速度传感器注册监听器
         *
         * SENSOR_DELAY_FASTEST 最快。延迟最小,只有特别依赖于传感器数据的应用推荐采用这种频率,该种模式可能造成手机电量大量消耗。由于传递的为原始数据,算法处理不好将会影响应用的性能。
         * SENSOR_DELAY_GAME 适合游戏的频率。一般有实时性要求的应用适合使用这种频率
         * SENSOR_DELAY_NORMAL 正常频率。一般对实时性要求不是特别高的应用适合使用这种频率。
         * SENSOR_DELAY_UI 适合普通用户界面的频率。这种模式比较省电,而且系统开销也很小,但延迟较大,因此只适合在普通小程序中使用。
         * */
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(
                        Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_UI); // ②
    }

    @Override
    public void onPause() {
        super.onPause();
        // 取消注册
        sensorManager.unregisterListener(this);
    }

    // 以下是实现SensorEventListener接口必须实现的方法
    // 当传感器的值发生改变时回调该方法
    @Override
    public void onSensorChanged(SensorEvent event) {
        float[] values = event.values;
        String sb = "X方向上的加速度:" +
                values[0] +
                "\nY方向上的加速度:" +
                values[1] +
                "\nZ方向上的加速度:" +
                values[2];
        etTxt1.setText(sb);
    }

    // 当传感器精度改变时回调该方法
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        
    }
}

常用传感器

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    // 定义Sensor管理器
    private SensorManager mSensorManager;
    private TextView etOrientation;
    private TextView etGyro;
    private TextView etMagnetic;
    private TextView etGravity;
    private TextView etLinearAcc;
    private TextView etTemerature;
    private TextView etHumidity;
    private TextView etLight;
    private TextView etPressure;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取界面上的TextView组件
        etOrientation = findViewById(R.id.etOrientation);
        etGyro = findViewById(R.id.etGyro);
        etMagnetic = findViewById(R.id.etMagnetic);
        etGravity = findViewById(R.id.etGravity);
        etLinearAcc = findViewById(R.id.etLinearAcc);
        etTemerature = findViewById(R.id.etTemerature);
        etHumidity = findViewById(R.id.etHumidity);
        etLight = findViewById(R.id.etLight);
        etPressure = findViewById(R.id.etPressure);
        // 获取传感器管理服务
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  // ①
    }

    @Override
    public void onResume() {
        super.onResume();
        // 为系统的方向传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的陀螺仪传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的磁场传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的重力传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的线性加速度传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的温度传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的湿度传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_RELATIVE_HUMIDITY),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的光传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
                SensorManager.SENSOR_DELAY_GAME);
        // 为系统的压力传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE),
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onPause() {
        // 程序暂停时取消注册传感器监听器
        mSensorManager.unregisterListener(this);
        super.onPause();
    }

    // 以下是实现SensorEventListener接口必须实现的方法
    // 当传感器精度改变时回调该方法
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        float[] values = event.values;
        // 获取触发event的传感器类型
        int sensorType = event.sensor.getType();
        StringBuilder sb;
        // 判断是哪个传感器发生改变
        switch (sensorType) {
            // 方向传感器
            case Sensor.TYPE_ORIENTATION:
                sb = new StringBuilder();
                sb.append("绕Z轴转过的角度:");
                sb.append(values[0]);
                sb.append("\n绕X轴转过的角度:");
                sb.append(values[1]);
                sb.append("\n绕Y轴转过的角度:");
                sb.append(values[2]);
                etOrientation.setText(sb.toString());
                break;
            // 陀螺仪传感器
            case Sensor.TYPE_GYROSCOPE:
                sb = new StringBuilder();
                sb.append("绕X轴旋转的角速度:");
                sb.append(values[0]);
                sb.append("\n绕Y轴旋转的角速度:");
                sb.append(values[1]);
                sb.append("\n绕Z轴旋转的角速度:");
                sb.append(values[2]);
                etGyro.setText(sb.toString());
                break;
            // 磁场传感器
            case Sensor.TYPE_MAGNETIC_FIELD:
                sb = new StringBuilder();
                sb.append("X轴方向上的磁场强度:");
                sb.append(values[0]);
                sb.append("\nY轴方向上的磁场强度:");
                sb.append(values[1]);
                sb.append("\nZ轴方向上的磁场强度:");
                sb.append(values[2]);
                etMagnetic.setText(sb.toString());
                break;
            // 重力传感器
            case Sensor.TYPE_GRAVITY:
                sb = new StringBuilder();
                sb.append("X轴方向上的重力:");
                sb.append(values[0]);
                sb.append("\nY轴方向上的重力:");
                sb.append(values[1]);
                sb.append("\nZ轴方向上的重力:");
                sb.append(values[2]);
                etGravity.setText(sb.toString());
                break;
            // 线性加速度传感器
            case Sensor.TYPE_LINEAR_ACCELERATION:
                sb = new StringBuilder();
                sb.append("X轴方向上的线性加速度:");
                sb.append(values[0]);
                sb.append("\nY轴方向上的线性加速度:");
                sb.append(values[1]);
                sb.append("\nZ轴方向上的线性加速度:");
                sb.append(values[2]);
                etLinearAcc.setText(sb.toString());
                break;
            // 温度传感器
            case Sensor.TYPE_AMBIENT_TEMPERATURE:
                sb = new StringBuilder();
                sb.append("当前温度为:");
                sb.append(values[0]);
                etTemerature.setText(sb.toString());
                break;
            // 湿度传感器
            case Sensor.TYPE_RELATIVE_HUMIDITY:
                sb = new StringBuilder();
                sb.append("当前湿度为:");
                sb.append(values[0]);
                etHumidity.setText(sb.toString());
                break;
            // 光传感器
            case Sensor.TYPE_LIGHT:
                sb = new StringBuilder();
                sb.append("当前光的强度为:");
                sb.append(values[0]);
                etLight.setText(sb.toString());
                break;
            // 压力传感器
            case Sensor.TYPE_PRESSURE:
                sb = new StringBuilder();
                sb.append("当前压力为:");
                sb.append(values[0]);
                etPressure.setText(sb.toString());
                break;
        }
    }
}

实例:指南针

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    // 定义显示指南针的图片
    private ImageView znzIV;
    // 记录指南针图片转过的角度
    private float currentDegree = 0f;
    // 定义Sensor管理器
    private SensorManager mSensorManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        znzIV = findViewById(R.id.znzImage);
        // 获取传感器管理服务
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    public void onResume() {
        super.onResume();
        // 为系统的方向传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onPause() {
        // 取消注册
        mSensorManager.unregisterListener(this);
        super.onPause();
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        // 获取触发event的传感器类型
        int sensorType = event.sensor.getType();
        switch (sensorType) {
            case Sensor.TYPE_ORIENTATION:
                // 获取绕Z轴转过的角度
                float degree = event.values[0];
                // 创建旋转动画(反向转过degree度)
                RotateAnimation ra = new RotateAnimation(currentDegree, -degree,
                        Animation.RELATIVE_TO_SELF, 0.5f,
                        Animation.RELATIVE_TO_SELF, 0.5f);
                // 设置动画的持续时间
                ra.setDuration(200);
                // 运行动画
                znzIV.startAnimation(ra);
                currentDegree = -degree;
                break;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}
image.png

实例:水平仪

MyView

public class MyView extends View {
    // 定义水平仪仪表盘图片
    Bitmap back;
    // 定义水平仪中的气泡图标
    Bitmap bubble;
    // 定义水平仪中气泡的X、Y坐标
    float bubbleX = 0f;
    float bubbleY = 0f;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 获取窗口管理器
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        // 获取屏幕的宽度和高度
        Display display = wm.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics(metrics);
        int screenWidth = metrics.widthPixels;
        // 创建位图
        back = Bitmap.createBitmap(screenWidth, screenWidth,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(back);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        // 设置绘制风格:仅填充
        paint.setStyle(Paint.Style.FILL);
        // 创建一个线性渐变来绘制线性渐变
        LinearGradient shader = new LinearGradient(0f, screenWidth, screenWidth * 0.8f,
                screenWidth * 0.2f, Color.YELLOW, Color.WHITE, Shader.TileMode.MIRROR);
        paint.setShader(shader);
        // 绘制圆形
        canvas.drawCircle(screenWidth / 2, screenWidth / 2, screenWidth / 2, paint);
        Paint paint2 = new Paint();
        paint2.setAntiAlias(true);
        // 设置绘制风格:仅绘制边框
        paint2.setStyle(Paint.Style.STROKE);
        paint2.setStrokeWidth(5f);  // 设置画笔宽度
        paint2.setColor(Color.BLACK); // 设置画笔颜色
        // 绘制圆形边框
        canvas.drawCircle(screenWidth / 2, screenWidth / 2, screenWidth / 2, paint2);
        // 绘制水平横线
        canvas.drawLine(0f, screenWidth / 2, screenWidth, screenWidth / 2, paint2);
        // 绘制垂直横线
        canvas.drawLine(screenWidth / 2, 0f, screenWidth / 2, screenWidth, paint2);
        paint2.setStrokeWidth(10f);  // 设置画笔宽度
        // 设置画笔颜色
        paint2.setColor(Color.RED);
        // 绘制中心的红色“十”字
        canvas.drawLine(screenWidth / 2 - 30, screenWidth / 2,
                screenWidth / 2 + 30, screenWidth / 2, paint2);
        canvas.drawLine(screenWidth / 2, screenWidth / 2 - 30,
                screenWidth / 2, screenWidth / 2 + 30, paint2);
        // 加载气泡图片
        bubble = BitmapFactory.decodeResource(getResources(), R.drawable.bubble);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制水平仪仪表盘图片
        canvas.drawBitmap(back, 0f, 0f, null);
        // 根据气泡坐标绘制气泡
        canvas.drawBitmap(bubble, bubbleX, bubbleY, null);
    }
}
public class MainActivity extends AppCompatActivity implements SensorEventListener {
    public final static int MAX_ANGLE = 30;
    // 定义水平仪的仪表盘
    private MyView show;
    // 定义Sensor管理器
    private SensorManager mSensorManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取水平仪的主组件
        show = findViewById(R.id.show);
        // 获取传感器管理服务
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    public void onResume() {
        super.onResume();
        // 为系统的方向传感器注册监听器
        mSensorManager.registerListener(this,
                mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    public void onPause() {
        // 取消注册
        mSensorManager.unregisterListener(this);
        super.onPause();
    }

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

    @Override
    public void onSensorChanged(SensorEvent event) {
        float[] values = event.values;
        // 获取触发event的传感器类型
        int sensorType = event.sensor.getType();
        switch (sensorType) {
            case Sensor.TYPE_ORIENTATION:
                // 获取与Y轴的夹角
                float yAngle = values[1];
                // 获取与Z轴的夹角
                float zAngle = values[2];
                // 气泡位于中间时(水平仪完全水平),气泡的X、Y坐标
                float x = (show.back.getWidth() - show.bubble.getWidth()) / 2;
                float y = (show.back.getHeight() - show.bubble.getHeight()) / 2;
                // 如果与Z轴的倾斜角还在最大角度之内
                if (Math.abs(zAngle) <= MAX_ANGLE) {
                    // 根据与Z轴的倾斜角度计算X坐标的变化值
                    // (倾斜角度越大,X坐标变化越大)
                    int deltaX = (int) ((show.back.getWidth() - show.bubble
                            .getWidth()) / 2 * zAngle / MAX_ANGLE);
                    x += deltaX;
                }
                // 如果与Z轴的倾斜角已经大于MAX_ANGLE,气泡应到最左边
                else if (zAngle > MAX_ANGLE) {
                    x = 0;
                }
                // 如果与Z轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
                else {
                    x = show.back.getWidth() - show.bubble.getWidth();
                }
                // 如果与Y轴的倾斜角还在最大角度之内
                if (Math.abs(yAngle) <= MAX_ANGLE) {
                    // 根据与Y轴的倾斜角度计算Y坐标的变化值
                    // (倾斜角度越大,Y坐标变化越大)
                    int deltaY = (int) ((show.back.getHeight() - show.bubble
                            .getHeight()) / 2 * yAngle / MAX_ANGLE);
                    y += deltaY;
                }
                // 如果与Y轴的倾斜角已经大于MAX_ANGLE,气泡应到最下边
                else if (yAngle > MAX_ANGLE) {
                    y = show.back.getHeight() - show.bubble.getHeight();
                }
                // 如果与Y轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最上边
                else {
                    y = 0;
                }
                // 如果计算出来的X、Y坐标还位于水平仪的仪表盘内,更新水平仪的气泡坐标
                if (isContain(x, y)) {
                    show.bubbleX = x;
                    show.bubbleY = y;
                }
                // 通知系统重绘MyView组件
                show.postInvalidate();
                break;
        }
    }

    // 计算x、y点的气泡是否处于水平仪的仪表盘内
    private boolean isContain(float x, float y) {
        // 计算气泡的圆心坐标X、Y
        float bubbleCx = x + show.bubble.getWidth() / 2;
        float bubbleCy = y + show.bubble.getHeight() / 2;
        // 计算水平仪仪表盘的圆心坐标X、Y
        float backCx = show.back.getWidth() / 2;
        float backCy = show.back.getHeight() / 2;
        // 计算气泡的圆心与水平仪仪表盘的圆心之间的距离
        double distance = Math.sqrt((bubbleCx - backCx) * (bubbleCx - backCx) +
                (bubbleCy - backCy) * (bubbleCy - backCy));
        // 若两个圆心的距离小于它们的半径差,即可认为处于该点的气泡依然位于仪表盘内
        return distance < (show.back.getWidth() - show.bubble.getWidth()) / 2;
    }
}
image.png

摘抄至《疯狂Android讲义(第4版)》

相关文章

  • Android传感器

    一.Android的三大类传感器 Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器...

  • 传感器

    一.Android的三大类传感器 Android传感器按大方向划分大致有三类传感器:动作(Motion)传感器、环...

  • Android传感器(第一篇)

    Android传感器定义 Android 传感器相关术语微机电传感器(MEMS)MEMS 通常制作在规格很小的硅芯...

  • Android传感器应用开发

    Android传感器应用开发 Android系统提供了对传感器的支持,如果手机设备的硬件提供了这些传感器,Andr...

  • Android开发高级进阶——传感器

    Android系统提供了对传感器的支持,如果手机设备的硬件提供了这些传感器,Android应用可以通过传感器来获取...

  • Android 传感器开发详解

    Android 传感器开发详解 传感器 传感器的分类 方向传感器 陀螺仪传感器 磁场传感器 重力传感器 线性加速度...

  • Android的传感器开发

    在Android系统中开发传感器应用十分简单,因为Android系统为传感器支持提供了强大的管理服务,同样传感器的...

  • android Sensor 安卓 传感器

    android Sensor 安卓 传感器 传感器基本使用 ''' 获取传感器管理器者 SensorManag...

  • Android手机传感器的简单介绍

    Android手机传感器的使用 1、传感器的分类 动作传感器:加速度传感器、重力传感器、陀螺仪等位置传感器:方向传...

  • 传感器实现仿微信摇一摇功能

    导语 如今Android手机中,硬件中内嵌了很多传感器(比如加速度传感器,重力传感器,陀螺仪传感器,方向传感器,压...

网友评论

      本文标题:Android 传感器

      本文链接:https://www.haomeiwen.com/subject/ycoqirtx.html