今天继续学习郭老师的第一行代码Android代码,学习传感器的部分,主要是学习了光照传感器、加速传感器、方向传感器以及地磁传感器,
并在郭老师光照传感器的案例上加上了自己的想法,当光照强度低于一定值得时候,自动打开手机的闪光灯,很便捷的操作,再者就是完成了
指南针的小项目。
由于代码很详细,直接上代码。
一、光照传感器并根据光照强度自动打开收电筒
MainActivity.java代码:
public class MainActivity extends ActionBarActivity {
private SensorManager sensorManager;
private TextView lightLevel;
private Camera m_Camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lightLevel=(TextView)findViewById(R.id.light_level);
//所有的传感器第一步都是去获取一个SensorManager实例,
sensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
//SenSorManager是系统所有传感器的管理器,有了它的实例之后就可以调用getDefaultSensor的方法来
//得到任意的传感器类型
Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
//注册一个传感器输出信号的监听器,第三个参数是传感器的类型
sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onDestroy()
{
super.onDestroy();
if (sensorManager!=null) {
sensorManager.unregisterListener(listener);
}
}
//SensorEventListener是一个接口,其中定义了onSensorChanged和AccuracyChanged
//两个方法,当传感器数值变化会调用onSensorChanged方法。
private SensorEventListener listener=new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//values数组中第一个下标的值就是当前的光照强度
float value=event.values[0];
lightLevel.setText("Current light level is"+value+"lx");
if(value<=5.0)
{
OpenLightOn();
}
else {
CloseLightOff();
}
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
};
private void OpenLightOn() {
if ( null == m_Camera )
{
//通过open函数获得一个Camera对象
m_Camera = Camera.open();
}
//通过函数 getParameters() 得到一个已有的 ( 默认的 ) 设置
Camera.Parameters parameters = m_Camera.getParameters();
设置照相机参数,FLASH_MODE_TORCH 持续的亮灯,FLASH_MODE_ON 只闪一下
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
//设置参数
m_Camera.setParameters( parameters );
//开始照明
m_Camera.startPreview();
}
private void CloseLightOff() {
if ( m_Camera != null )
{
m_Camera.stopPreview();
m_Camera.release();
m_Camera = null;
}
}
}
activity_main.xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/light_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" >
</TextView>
</LinearLayout>
配置文件代码:
<!-- 开启照相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.autofocus" />
<!--uses_feature表示需要的硬件功能 -->
<!-- 开启闪光灯权限 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
二、地磁传感器、加速度传感器及指南针项目
MainActivity.java代码:
package com.example.compasstest;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
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.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.os.Build;
/**
*
*Android获取手机旋转方向和角度是通过加速传感器和地磁传感器共同计算得出的。
*/
public class MainActivity extends ActionBarActivity {
private SensorManager sensorManager;
private ImageView compassImg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
compassImg = (ImageView) findViewById(R.id.compass_img);
//实例化一个SenorManager对象
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//通过SensorManager的实例化对象来获得地磁传感器的对象
Sensor magneticSensor = sensorManager
.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//获取加速传感器的对象
Sensor accelerometerSensor = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//注册地磁感应器的监听器
sensorManager.registerListener(listener, magneticSensor,
SensorManager.SENSOR_DELAY_GAME);
//注册加速传感器的监听器,最后一个参数为传感器的输出信息的更新速率
/*
* SENSOR_DELAY_NOMAL (200000微秒)
*SENSOR_DELAY_UI (60000微秒)
* SENSOR_DELAY_GAME (20000微秒)
* SENSOR_DELAY_FASTEST (0微秒)
*/
sensorManager.registerListener(listener, accelerometerSensor,
SensorManager.SENSOR_DELAY_GAME);
}
//活动销毁时调用的方法
protected void onDestroy() {
super.onDestroy();
if (sensorManager != null) {
sensorManager.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) {
accelerometerValues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticValues = event.values.clone();
}
//R数组用来存储getRotationMatrix计算的数据
float[] R = new float[9];
float[] values = new float[3];
SensorManager.getRotationMatrix(R, null, accelerometerValues,magneticValues);
//计算手机的旋转数据
sensorManager.getOrientation(R,values);
//用getOrientation的计算数据,计算后的数据存入Values数组
//将弧度转换成角度并取反,用于背景图 的旋转
float rotateDegree = -(float) Math.toDegrees(values[0]);
if (Math.abs(rotateDegree - lastRotateDegree) > 1) {
//六个参数,第一个是起始角度,第二个是终止角度,后四个参数是旋转中心
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 arg0, int arg1) {
// TODO Auto-generated method stub
}
};
}
activity_main.xml代码
<ImageView
android:id="@+id/compass_img"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:src="@drawable/compass" >
</ImageView>
<ImageView
android:id="@+id/arrow_img"
android:layout_width="40dp"
android:layout_height="120dp"
android:layout_alignTop="@+id/compass_img"
android:layout_centerHorizontal="true"
android:layout_marginTop="27dp"
android:src="@drawable/arrow" />
无需进行配置文件的配置。
最后附一张指南针项目的截图,UI有点丑,见谅!