android开发:传感器的实例light,proximity,accelerometer,SensorManager,Sensor(含步数计算原理)

直接上代码吧,一会再加一张图片:

package com.lanxin.testsensor;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private static final String TAG = "TestSensorLog";
    private TextView textView,textview2,textview3;
    private Button but1;
    private FloatingActionButton fab;

    private SensorManager sensorManager;
    private List<Sensor> sensor;
    private Sensor light,proximity,accelerometer;
    private Context mContext;
    private int mRotation;
    private float[] motion = new float[3];
    private float[] gravity = new float[3];

    private int count = 0;

    String str;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        init();

    }

    private void init() {
        mContext = this;
        but1 = (Button) findViewById(R.id.but1);
        textView = (TextView) findViewById(R.id.textview);
        textview2 = (TextView) findViewById(R.id.textview2);
        textview3 = (TextView) findViewById(R.id.textview3);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensor = sensorManager.getSensorList(Sensor.TYPE_ALL);
        light = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        but1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                StringBuilder sb = new StringBuilder();

                for (Sensor s:sensor){
                    sb.append("传感器名称:"+s.getName()+"\n");
                    sb.append("传感器类型:"+s.getType()+"\n");
                    sb.append("传感器供应商:"+s.getVendor()+"\n");
                    sb.append("传感器版本:"+s.getVersion()+"\n");
                    sb.append("传感器分辨率:"+s.getResolution()+"\n");
                    sb.append("传感器最大射程:"+s.getMaximumRange()+"\n");
                    sb.append("传感器功率:"+s.getPower()+"\n");
                    sb.append("\n\n");

                }
                textView.setText(sb);
            }
        });

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sensorManager.registerListener((SensorEventListener) mContext,light,
                        SensorManager.SENSOR_DELAY_NORMAL);

                sensorManager.registerListener((SensorEventListener) mContext, proximity,
                        SensorManager.SENSOR_DELAY_NORMAL);

                sensorManager.registerListener((SensorEventListener) mContext, accelerometer,
                        SensorManager.SENSOR_DELAY_NORMAL);
            }
        });

        WindowManager window = (WindowManager) this.getSystemService(WINDOW_SERVICE);
        mRotation = window.getDefaultDisplay().getRotation();

    }
    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this, light);
        sensorManager.unregisterListener(this, proximity);
        sensorManager.unregisterListener(this,accelerometer);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        float val = sensorEvent.values[0];
        String tag = "";

        switch (sensorEvent.sensor.getType()){
            case Sensor.TYPE_LIGHT:
                if (val < 20){
                    tag = "在室内没开灯";
                }else if (val < 500 && val > 20){
                    tag = "在室内并开灯了";
                }else if (val < 3000 && val > 499){
                    tag = "你在室外";
                }else if (val > 3000){
                    tag = "你在晒太阳吗?";
                }


                textView.setText("感光度测试:\n"+
                                "感光度:"+val+"\n" +
                                "信息:"+tag+"\n"
                );

                break;
            case Sensor.TYPE_PROXIMITY:
                textview3.setText("接近传感器:\n"+
                                "距离:"+val+"\n" +
                                "信息:"+(val == 0 ? "走开别靠近我" : "你离我那么远干嘛?")+"\n"
                );
                break;
            case Sensor.TYPE_ACCELEROMETER:
                count++;

                tag = String.format("加速传感器(初始值):\nX: %8.4f\nY: %8.4f\nZ: %8.4f\n",
                        sensorEvent.values[0], sensorEvent.values[1], sensorEvent.values[2]);

                //低通过滤
                for (int i=0;i<3;i++){
                    gravity[i] = (float) (0.1 * sensorEvent.values[i] + 0.9 * gravity[i]);
                    motion[i] = sensorEvent.values[i] - gravity[i];
                }

                double ratio = gravity[1] / SensorManager.GRAVITY_EARTH;
                if(ratio > 1.0) ratio =  1.0;
                if(ratio < -1.0) ratio =  -1.0;

                //角度的计算
                double Angle = Math.toDegrees(ratio);
                if(gravity[2] < 0){
                    Angle = -Angle;
                }

                double gravityNew = Math.sqrt(
                        sensorEvent.values[0] * sensorEvent.values[0] +
                        sensorEvent.values[1] * sensorEvent.values[1] +
                        sensorEvent.values[2] * sensorEvent.values[2]
                );

                tag += String.format("重力:\nX:%8.4f\nY:%8.4f\nZ:%8.4f\n", gravity[0],gravity[1],gravity[2]);
                tag += String.format("运动:\nX:%8.4f\nY:%8.4f\nZ:%8.4f\n", motion[0],motion[1],motion[2]);
                tag += "角度:"+Angle+"\n平方根:"+gravityNew+"\n步数:"+stepNUM+"\n";

                countStep((float) gravityNew);

                if(count > 10){
                    count = 0;


                    textview2.setText(tag);
                }

                break;
        }


    }

    /**
     * 检测步子,并开始计步
     * @param val
     */
    private void countStep(float val){
        if(stepOld == 0){
            stepOld = val;
        }else {
            if(DetectorPeak(val,stepOld)){
                timeOfLastPeak = timeOfThisPeak;
                timeOfNow = System.currentTimeMillis();
                if(timeOfNow - timeOfLastPeak >= 250
                        && (peakOfWave - valleyOfWave >= ThreadValue)){
                    timeOfThisPeak = timeOfNow;
                    //步数累计
                    stepNUM++;
                }

                if(timeOfNow - timeOfLastPeak >= 250
                        && (peakOfWave - valleyOfWave > initialValue)){
                    timeOfThisPeak = timeOfNow;
                    ThreadValue = Peak_Valley_Thread(peakOfWave - valleyOfWave);
                }

            }
        }
        stepOld = val;
    }

    int stepNUM = 0;
    float stepOld = 0;
    boolean isDirectionUp = false;//是否上升的标志位
    boolean lastStatus = false;//上一点的状态,上升还是下降
    int continueUpCount = 0;//持续上升次数
    int continueUpFormerCount = 0; //上一点的持续上升的次数,为了记录波峰的上升次数
    float peakOfWave = 0;//波峰值
    float valleyOfWave = 0;  //波谷值
    long timeOfLastPeak = 0L;
    long timeOfThisPeak = 0L;
    long timeOfNow  = 0L;
    float ThreadValue = (float) 2.0;//初始阈值
    float initialValue = (float) 1.3;//动态阈值需要动态的数据,这个值用于这些动态数据的阈值

    //计算波峰阈值的数据
    int tempCount = 0;
    int valueNum = 4;
    float[] tempValue = new float[valueNum];//用于存放计算阈值的波峰波谷差值

    /**
     * 检测波峰
     * @param newVal
     * @param oldVal
     * @return
     */
    private boolean DetectorPeak(float newVal,float oldVal){
        lastStatus = isDirectionUp;
        if(newVal >= oldVal){
            isDirectionUp = true;
            continueUpCount++;
        }else {
            continueUpFormerCount = continueUpCount;
            continueUpCount = 0;
            isDirectionUp = false;
        }

        if(isDirectionUp && lastStatus && (continueUpFormerCount >=2 || oldVal  >= 11)){
            peakOfWave = oldVal;
            return true;
        }else if (!lastStatus && isDirectionUp){
            valleyOfWave = oldVal;
            return false;
        }else {
            return false;
        }
    }

    /**
     * 阈值的计算
     * @param val
     * @return
     */
    private float Peak_Valley_Thread(float val){
        float temp = ThreadValue;
        if(tempCount < valueNum){
            tempValue[tempCount] = val;
            tempCount++;
        }else {
            temp = averageValue(tempValue,valueNum);
            for (int i=1; i<valueNum;i++){
                tempValue[i-1] = tempValue[i];
            }
            tempValue[valueNum-1] = val;
        }
        return temp;
    }

    /**
     * 梯度化阈值
     * @param val
     * @param n
     * @return
     */
    private float averageValue(float val[],int n){
        float ave = 0;
        for (int i=0; i < n; i++){
            ave += val[i];
        }

        ave = ave / valueNum;

        if(ave >= 8){
            ave = (float)4.3;
        }else if (ave >=7 && ave < 8){
            ave = (float)3.3;
        }else if (ave >=4 && ave < 7){
            ave = (float)2.3;
        }else if (ave >=3 && ave < 4){
            ave = (float)2.0;
        }else {
            ave = (float)1.3;
        }
        return ave;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
//        textview2.setText(
//                "感光传感器:\n"+
//                "名称:"+sensor.getName()+"\n" +
//                "精准度:"+i+"\n" +
//                        "电量:"+sensor.getPower()+"\n" +
//                "最大射程:"+sensor.getMaximumRange()+"\n"+
//                "厂商:"+sensor.getVendor()+"\n" +
//                "版本:"+sensor.getVersion()+"\n"
//        );
    }
}

 

 

234233714525766533

Leave a Comment