Android学习——传感器

传感器

概述

大多数安卓设备都内置了传感器,用来测量移动,方向和各种环境条件。
Android平台支持以下三类传感器:

  • 这些传感器能够提供精度高且准确的原始数据。
  • 如果要监视三维设备运动或定位,或者监视设备周围的环境变化,那么传感器会极其有用。
  • 例如:游戏可以追踪设备重力感应器的读数来推断复杂的用户手势和动作,比如倾斜,摇晃,旋转或摆动。
  • 同样地,天气应用程序可以使用设备温度传感器和湿度传感器来计算并报告dewpoint,旅行应用程序可以使用地磁传感器和加速计来报告罗盘方位。

1.运动传感器:这些传感器测量三个轴的加速力和旋转力。这一类别包括加速度计,重力感应器,陀螺仪和旋转矢量传感器。
2.环境传感器:这些传感器测量各种环境参数,例如环境空气温度和压力,照明和湿度。此类别包括了气压计,光度计和温度计。
3.位置传感器:这些传感器测量了设备的物理位置。此类别包括方向传感器和磁力计。

Google文档上把传感器类型分为传感器坐标轴、基础传感器和复合传感器(动作传感器、姿势传感器、未校准传感器和互动传感器)

更加具体的可以参考:https://source.android.google.cn/devices/sensors/sensor-types

获取本机支持的传感器

Android传感器框架是android.hardware包的一部分,包含下面的类和接口:

  • SensorManager :你能使用这个类来创建一个传感器服务的实例。这个类提供了各种方法类访问和列举传感器,注册和注销传感器事件监听,并获取相应的信息。这个类也提供了几个传感器的常量,用户报告传感器的精确度,设置数据获取速率,和校准传感器。
  • Sensor :你能使用这个类类创建一个指定传感器的实例。这个类提供了各种方法让你确定传感器的功能。
  • SensorEvent :系统使用这个类来创建一个传感器对象,它提供了关于传感器事件的信息。一个传感器事件包含一下信息:原始传感器数据,这类传感器产生的事件,数据的准确性,和事件的时间戳。
  • SensorEventListener :你能使用这个接口来创建两个回掉方法,当传感器的值改变或者当传感器的精度改变的时候,它接受通知(传感器事件)
        SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

获取本机全部传感器列表

package com.example.sensor;

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

import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //获取系统传感器
        SensorManager sm= (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        //通过传感器获取本机所有的传感器
        List<Sensor> sensors=sm.getSensorList(Sensor.TYPE_ALL);
        for (Sensor s:sensors){
            Log.i("tag",s.toString());
        }
    }
}

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述

获取指定传感器

可以通过下图的代码来获取指定的传感器, 需要选择合适的传感器类型
在这里插入图片描述
返回一个Sensor对象

        //获取指定的某一个传感器,下面为加速度传感器
        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) {
                //传感器数据变化,在该方中我们可以获取传感器变化的值
            }

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

传感器坐标系

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

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

许多传感器的传感器事件值在相对于设备静止的特定坐标系中表示。
在这里插入图片描述

        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_content.setText("x="+x+"y="+y+"z="+z);
            }

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

在这里插入图片描述

摇一摇

使用加速传感器实现摇一摇功能

Sensor type_accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sm.registerListener(new MySensorListener(this) ,type_accelerometer,SensorManager.SENSOR_DELAY_NORMAL);

摇一摇打开音乐
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/content"
        android:text="Hello World!" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="开始啦"
        android:background="@android:color/holo_blue_light"
        android:textSize="70sp"
        android:visibility="gone"
        android:gravity="center"
        android:id="@+id/textView_start"
        android:layout_gravity="center" />

</RelativeLayout>
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_content,textView_start;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView_content=findViewById(R.id.content);
        textView_start=findViewById(R.id.textView_start);

        //获取系统传感器
        SensorManager sm= (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        //通过传感器获取本机所有的传感器
        final List<Sensor> sensors=sm.getSensorList(Sensor.TYPE_ALL);
        for (Sensor s:sensors){
            Log.i("tag",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_content.setText("x="+x+"y="+y+"z="+z);
//                Log.i("tag","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.fyzx);
                    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;//表示是否已经在播放声音
}

温度传感器

        Sensor type_ambient_temperature=sm.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
        if (type_ambient_temperature != null) {
            System.out.println(type_ambient_temperature.toString());
        }
        sm.registerListener(new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                float temp=event.values[0];
                System.out.println(temp);
                temp= (float) (Math.round(temp*10.0)/10.0);
                textView_temp.setText("温度:"+temp+"℃");
            }

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

            }
        },type_ambient_temperature,SensorManager.SENSOR_DELAY_NORMAL);
    }

自由的小方

  1. 定义一个小方块对象
  2. 定义一个视图,用于把小方块配置到屏幕上
  3. 通过重力传感器TYPE_GRAVIY控制小方块在屏幕上自由的行走(注意,自由是有一个度的,不能超出屏幕)
    在这里插入图片描述
    设置全屏
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen"

定义一个小方块对象

package com.example.sensor;

public class Rect {
    float left=100,top=100,right=100,bottom=100;
    private int width,height;
    public Rect(int width,int height)
    {
        this.width=width;
        this.height=height;
        left=width/2-right/2;
        top=height/2-bottom/2;

    }

    public float getBottom() {
        return bottom;
    }

    public void setBottom(float bottom) {
        this.bottom = bottom;
    }

    public float getLeft() {
        return left;
    }

    public void setLeft(float left) {
        this.left -= left;
        if (this.left<=0)
        {
            this.left=0;
        }
        else if (this.left>=width-this.right)

        {
            this.left=width-this.right;
        }
    }

    public float getRight() {
        return right;
    }

    public void setRight(float right) {
        this.right = right;
    }

    public float getTop() {
        return top;
    }

    public void setTop(float top) {
        this.top+= top;
        if (this.top<=0)
        {
            this.top=0;
        }
        else if ( this.top>=height-this.bottom)
        {
            this.top=height-this.bottom;
        }
    }
}

定义一个视图

package com.example.sensor;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class RectView extends View {
    Rect rect;
    private int width,height;
    Paint paint;
    public RectView(Context context, int width, int height) {
        super(context);
        this.width=width;
        this.height=height;
        paint =new Paint();
        paint.setColor(Color.GREEN);
        rect=new Rect(width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(rect.getLeft(),rect.getTop(),rect.getRight()+rect.getLeft(),rect.getTop()+rect.getBottom(),paint);
    }
}

通过重力传感器TYPE_GRAVIY控制小方块在屏幕上自由的行走

package com.example.sensor;

import android.app.Activity;
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.DisplayMetrics;

public class Main2Activity extends Activity {
    private RectView rectView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //获取屏幕宽高
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        rectView = new RectView(this, dm.widthPixels, dm.heightPixels);
        setContentView(rectView);
        SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor type_gravity = sm.getDefaultSensor(Sensor.TYPE_GRAVITY);
        sm.registerListener(new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                float x = event.values[0];
                float y = event.values[1];
                rectView.rect.setLeft(Math.round(x));
                rectView.rect.setTop(Math.round(y));
                rectView.invalidate();//屏幕重绘
            }

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

            }
        }, type_gravity, SensorManager.SENSOR_DELAY_GAME);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值