• 作者:老汪软件技巧
  • 发表时间:2024-11-01 21:02
  • 浏览量:

因为项目需要利用到了Android手机中的加速度传感器来获取三个加速度轴的加速度大小,同时也可以实现自定义采样频率,这个我写了一个类,通过类来控制。

获取加速度数据总体来说比较简单,首先获取服务:

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

然后在onResume()方法中注册监听器,开始使用加速度传感器:

sm.registerListener(this, SensorManager.SENSOR_ORIENTATION
				| SensorManager.SENSOR_ACCELEROMETER,
				simpleRate.get_SENSOR_RATE_FAST());

接着是很重要的一步,在onDestory()方法中解除监听器,不然加速度传感器会一直工作,很浪费电。还有需要注意的是,手机屏幕暗掉的时候,加速度传感器还是会工作的,如果想要屏幕暗掉的时候加速度传感器步工作,则需要在onPause()方法中解除监听器。

	@Override
	protected void onStop() {
		// unregister listener
		sm.unregisterListener(this);
		super.onStop();
	}

接下来是自定义采样频率:

注册监听器的时候最后一个参数是延迟时间,其实也就是采样频率,单位是微秒。只需要写入数字即可控制采样频率,这里通过一个类实现:

SimpleRate.java

package com.llp.classdifine;
 
/**
 * 加速度传感器采样率设定
 * 
 * @author Liu_Longpo
 * 
 */
public class SimpleRate {
 
	/**
	 * 50Hz
	 */
	private int SENSOR_RATE_NORMAL = 20000;
	/**
	 * 80Hz
	 */
	private int SENSOR_RATE_MIDDLE = 12500;
	/**
	 * 100Hz
	 */
	private int SENSOR_RATE_FAST = 10000;
 
	public SimpleRate() {
	};
 
	/**
	 * 50Hz
	 * @return
	 */
	public int get_SENSOR_RATE_NORMAL() {
		return this.SENSOR_RATE_NORMAL;
	}
 
	/**
	 * 80Hz
	 * 
	 * @return
	 */
	public int get_SENSOR_RATE_MIDDLE() {
		return this.SENSOR_RATE_MIDDLE;
	}
 
	/**
	 * 100Hz
	 * 
	 * @return
	 */
	public int get_SENSOR_RATE_FAST() {
		return this.SENSOR_RATE_FAST;
	}
 
}

MainActivity.java 代码如下:

陀螺仪数据采集报告__陀螺仪采集的是角度还是角速度

package com.llp.acceleration;
 
import java.io.File;
import java.util.ArrayList;
 
import android.app.Activity;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 
import com.llp.classdifine.FileService;
import com.llp.classdifine.SimpleRate;
 
public class MainActivity extends Activity implements SensorListener {
	SensorManager sm = null;
	TextView acx = null;
	TextView acy = null;
	TextView o = null;
	EditText fileName;
	EditText contentWrite;
	Button btnSave;
	Button btnRead;
	EditText contentRead;
	String mfileName;
	private FileService fileService;
 
	double ax = 0;
	double ay = 0;
	double oy = 0;
	double oz = 0;
	double axp = 0;
	double ayp = 0;
	double g = 10;
	double gp = 0;
 
	/**
	 * 采样频率设定
	 */
	public SimpleRate simpleRate;
	// ArrayList mDataListX = new ArrayList();
	// ArrayList mDataListY = new ArrayList();
	// ArrayList mDataListZ = new ArrayList();
	double tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0;
 
	/**
	 * 获取X轴加速度
	 * 
	 * @return
	 */
	public double getAccelerationX() {
		return axp;
	}
 
	/**
	 * 获取Y轴加速度
	 * 
	 * @return
	 */
	public double getAccelerationY() {
		return ayp;
	}
 
	/**
	 * 获取Z轴加速度
	 * 
	 * @return
	 */
	public double getOrientation() {
 
		return Math.asin(tmp4) / Math.PI * 180.0;
	}
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// get reference to SensorManager
 
		simpleRate = new SimpleRate();
		sm = (SensorManager) getSystemService(SENSOR_SERVICE);
		setContentView(R.layout.activity_main);
 
		/**
		 * 创建文件夹
		 */
		File sd = Environment.getExternalStorageDirectory();
		String mPath = sd.getPath() + "/datas";
		File file = new File(mPath);
		if (!file.exists()) {
			file.mkdir();
		}
		/**
		 * 控件初始化
		 */
		initView();
 
		btnSave.setOnClickListener(new View.OnClickListener() {
 
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mfileName = fileName.getText().toString();
//				saveAcceleration(mfileName);
			}
 
		});
	}
 
	/**
	 * 保存加速度数据
	 * 
	 * @param FileName
	 * @param content
	 */
	public void saveAcceleration(String FileName, String content) {
		try {
			// 判断sd卡是否存在手机上并且可以进行读写
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				fileService.write2Path(FileName, content);
			} else {
			}
		} catch (Exception e) {
			Log.v("test", e.toString());
		}
	}
 
	public void initView() {
		acx = (TextView) findViewById(R.id.xbox);
		acy = (TextView) findViewById(R.id.ybox);
		o = (TextView) findViewById(R.id.obox);
		fileName = (EditText) findViewById(R.id.fileName);
		contentWrite = (EditText) findViewById(R.id.content);
		btnSave = (Button) findViewById(R.id.btnsave);
		btnRead = (Button) findViewById(R.id.btnread);
		contentRead = (EditText) findViewById(R.id.contentread);
	}
 
	public void onSensorChanged(int sensor, float[] values) {
		synchronized (this) {
			if (sensor == SensorManager.SENSOR_ORIENTATION) {
				oy = values[1];
				oz = values[2];
			}
			if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
				ax = values[0];
				ay = values[1];
			}
 
			tmp1 = Math.sin(oz * Math.PI / 180.0);
			tmp2 = Math.sin(Math.abs(oy) * Math.PI / 180.0);
			tmp3 = Math.sqrt(tmp1 * tmp1 + tmp2 * tmp2);
			tmp4 = tmp1 / tmp3;
 
			gp = 10 * tmp3;
			axp = ax * Math.cos(tmp4) + ay * Math.sin(tmp4);
			ayp = -ax * Math.sin(tmp4) + ay * Math.cos(tmp4) + gp;
			acx.setText("a X: " + getAccelerationX());
			acy.setText("a Y: " + getAccelerationY());
			o.setText("Orientation : " + getOrientation());
			// mDataListX.add(getAccelerationX() + "\n");
			// mDataListY.add(getAccelerationY() + "\n");
			// mDataListZ.add(getOrientation() + "\n");
		}
	}
 
	public void onAccuracyChanged(int sensor, int accuracy) {
	}
 
	@Override
	protected void onResume() {
		super.onResume();
		// register this class as a listener for the orientation and
		// accelerometer sensors
		sm.registerListener(this, SensorManager.SENSOR_ORIENTATION
				| SensorManager.SENSOR_ACCELEROMETER,
				simpleRate.get_SENSOR_RATE_FAST());
	}
 
	@Override
	protected void onStop() {
		// unregister listener
		sm.unregisterListener(this);
		super.onStop();
	}
}

通过采集的x\y\z方向的数据计算出角度的算法如下

方法1:

fun calculation(x: Float, y: Float, z: Float): Float {
    val value = (abs(x.toDouble()) / 10f).toFloat()
    var angle: Float
    //值大于1 反三角函数无法计算需要特殊处理
    angle = if (value >= 1) {
        90f
    } else {
        Math.toDegrees(asin(value.toDouble())).toFloat()
    }
    if (isLeft(x)) {
        if (angle>15){
            angle=15f
        }
        angle = -angle
    }
    return angle
}
/**
 * 是否向左倾
 *
 * @return true 向左倾 false向右倾
 */
fun isLeft(x: Float): Boolean {
    return x < 0
}

方法2:

fun calculateAngle(px: Float, py: Float): Double {
    val value = (abs(px.toDouble()) / 10f).toFloat()
    var angle =Math.toDegrees(value.toDouble())
    if (px<0){
        if (Math.abs(angle)>mMaxAngle){
            angle= (-45).toDouble()
        }
        angle=-angle
    }else{
        if (Math.abs(angle)>mMaxAngle){
            angle= (45).toDouble()
        }
    }
    
    return angle
}

方法3:

private fun calculationHorizontal(x: Float): Float {
    val value = (abs(x.toDouble()) / 10f).toFloat()
    var angle: Float
    //值大于1 反三角函数无法计算需要特殊处理
    angle = if (value >= 1) {
        90f
    } else {
        Math.toDegrees(asin(value.toDouble())).toFloat()
    }
    val isLeft = x < 0
    if (isLeft) {
        angle = -angle
    }
    return angle
}

最后打印效果

image.png


上一条查看详情 +深入理解 XML Schema Definition (XSD)
下一条 查看详情 +没有了