光照传感器
>1. 先获取到SensorManager 的实例
SensorManager sensorManger=(SensorManager)getSystemSer(Context.SENSOR_SERVICE);
SensotManager是系统所有传感器的管理器,有了它的实例以后就可以调用
getDefaultSensor()方法来得到任意的传感器类型了,如下所示:
Sensor sensor=sensorManager.getDafaultSensor(Sensor.TYPE_LIGHT);
这里使用Sensor.TYPE_LIGHT常量来指定传感器的类型,此时的Sensor
实例就代表着一个光照传感器。
接下来我们对传感器的输出进行监听
SensorEventListener listener = new SensorEventListener(){
@override
public void onAccuranyChanged(Sensor sensor,int accuracy){
}
@override
public void onSensorChanged(SensorEvent event){
}
};
当传感器的精度发生变化时就会调用onAccuracyChanged()方法,当传感器检测到数值发生变化时就会调用onSensorChanged()方法。可以看到onSensorChanged()方法中传入了一个SensorEvent参数,这个参数里又包含了一个values数组,所有传感器的输出信息都存放在这里。
下面我们还需要使用SensorManager的registerListener()方法来注册SensorEventListener才能使其生效,registerListener()方法接收三个参数,第一个参数是SensotEventListener的实例,第二个参数是Sensor的实例,这两个参数我们已经在前面得到,第三个参数表示传感器输出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、SENSOR_DELAY_GAME、SENSOR_DELAY_FASTER四种值可选,更新速率是依次递增的。
因此可以写为:
sensorManager.registerListener(listener,sensor,SennsorManager.SENSOR_DELAY_NORMAL);
另外始终要记得,当程序退出或传感器使用完毕时,一定要调用unregisterListener()方法将使用的资源释放掉,
如下所示:
sensorManager.unregisterListener(listener);
示例
主程序
package com.test.lightsensortestsetemberseven;
import android.support.v7.app.ActionBarActivity;
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.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity {
private SensorManager mSensorManager;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView=(TextView) findViewById(R.id.light_level);
mSensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
mSensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mSensorManager!=null){
mSensorManager.unregisterListener(listener);
}
}
private SensorEventListener listener=new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float value=event.values[0];
mTextView.setText("Current light level is "+value+"lx");
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
}
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/light_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:textSize="20sp" />
</RelativeLayout>
加速度传感器
使用加速度传感器需要注意以下两点
第一,获取Sensor的实例的时候一定要指定一个加速度传感器的常量,如下:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
第二,加速度传感器输出的信息同样存放在SensorEvent的values数组中,只不过此时的values数组中会有三个值,分别代表着手机在X轴、Y轴和Z轴方向上的加速度信息。X轴、Y轴、Z轴在空间中的坐标图
另外需要注意的是,由于地心引力的存在,你的手机无论怎样放置都会受到地心引力的作用,这个加速度值大约为9.8m/s,当手机平放时这个加速度作用在Z轴,当你把手竖起来时这个力作用在Y轴,横立起来时作用在X轴。
当然,这个程序是一个非常简单的例子,你还可以在很多方面对它进行优化,比如说控制触发的频率,使它在短时间内不能连续触发两次等。更加缜密的逻辑就靠你去判断了。
示例:摇一摇程序
主程序
package com.test.accelerometersensortestsetemberseven;
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.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends Activity {
private SensorManager mSensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mSensorManager!=null){
mSensorManager.unregisterListener(listener);
}
}
private SensorEventListener listener=new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float xValue=Math.abs(event.values[0]);
float yValue=Math.abs(event.values[1]);
float zValue=Math.abs(event.values[2]);
if(xValue>15||yValue>15||zValue>15){
Toast.makeText(MainActivity.this, "山寨摇一摇", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
}
方向传感器
首先我们需要分别获取到加速度传感器和地磁传感器的实例,并给他们注册监听器,如下所示:
"Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(listener,accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener,magneticSensor,SensorManager.SENSOR_DELAY_GAME);”
由于方向传感器的精确度要求较高,这里我们把传感器的输出信息的更新速率提高了一些。
接下来在onSensorChanged()方法中可以获取到SensorEvent的values数组,分别记录着加速度传感器和地磁传感器输出的值,然后将着两个数值传入到SensorManager的getRotationMatrix()方法中就可也得到一个包含旋转矩阵的R数组,如下所示:
SensorManager.getRotationMatrix(R,null,accelerometerValues,magneticValues);
其中第一个参数R是一个长度为9的float数组,getRotationMatrix()方法计算出的旋转数据就会赋值到这个数组当中,第二个参数时一个用于将地磁向量转换成重力坐标的旋转矩阵,通常指定null即可。第三个参数和第四个参数则分别就是加速度传感器和地磁传感器输出的values值。
然后调用
SensorManager.getOrientation(R,values);
其中values[0]记录着手机围绕z轴的旋转弧度,values[1]代表着手机围绕x轴的旋转弧度,valuew[2]代表着手机围绕y轴的旋转弧度。
将弧度转化为角度的方法:
Math.toDegrees(values[0]);
示例:指南针
主程序
package com.test.compasstest;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
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.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
public class MainActivity extends Activity {
private SensorManager mSensorManager;
private ImageView compassImg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compassImg=(ImageView) findViewById(R.id.compass_img);
mSensorManager=(SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor magneticSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Sensor accelerometerSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(listener, magneticSensor,SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(listener, accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mSensorManager!=null){
mSensorManager.unregisterListener(listener);
}
}
private SensorEventListener listener=new SensorEventListener() {
float[] accelerometerValues=new float[3];
float[] magneticValues=new float[3];
private float lastRotateDegree;
@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
//注意赋值时调用clone()方法,否则会指向同一个引用。
accelerometerValues=event.values.clone();
}else if(event.sensor.getType()==Sensor.TYPE_MAGNETIC_FIELD){
//注意赋值时调用clone()方法,否则会指向同一个引用。
magneticValues=event.values.clone();
}
float[] R=new float[9];
float[] values = new float[3];
SensorManager.getRotationMatrix(R, null, accelerometerValues, magneticValues);
SensorManager.getOrientation(R, values);
/**
* values[0]的取值范围是-180度到180度,其中+-180度表示正南方向,
* 0度表示正北方向,-90代表正西方向,+90度代表证东方向
*/
float rotateDegree =- (float)Math.toDegrees(values[0]);
if(Math.abs(rotateDegree-lastRotateDegree)>6){
RotateAnimation animation=new RotateAnimation(lastRotateDegree, rotateDegree,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animation.setFillAfter(true);
compassImg.startAnimation(animation);
lastRotateDegree=rotateDegree;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
}
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/compass_img"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:src="@drawable/img_background_imageview_userinfo_cover"/>
<ImageView
android:id="@+id/arrow_img"
android:layout_width="60dp"
android:layout_height="110dp"
android:layout_centerInParent="true"
android:src="@drawable/img_textview_mediascan_wifi_on"/>
</RelativeLayout>