原文链接地址:http://blog.csdn.net/aiynmimi/article/details/48660505

简介

现在每部Android手机里边都会内置有许多传感器,如光照传感器、加速度传感器、地磁传感器、压力传感器、温度传感器等,它们能够监测到各种发生在手机撒花姑娘的物理事件。当然Android系统只是负责将这些传感器所输出的信息传递给我们,然后我们可以利用这些信息去开发一些好玩的应用。

用法

每种传感器的用法步骤几乎都一样,只是不同传感器的数据参数会有略微不同,这里以光照传感器为例,介绍一些Android传感器的使用步骤: 
①获取SensorManager的实例

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">SensorManager sensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

②SensorManager是系统所有传感器的管理器,有了它的实例后就可以调用getDefaultSensor()方法来得到任意的传感器类型。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_LIGHT);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

③然后我们需要对传感器输出的信号进行监听,这就要借助SensorEventListener来实现,SensorEventListener是一个接口,其中定义了onSensorChanged()和onAccuracyChanged()两个方法。当传感器的精度发生变化时就会调用onAccuracyChanged()方法,当监测到的数值发生变化时就会调用onSensorChanged()方法,方法中传入一个SensorEvent参数,这个参数里又包含一个values数组,所有传感器输出的信息都存放在这里。

SensorEventListener listener=new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {    }@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};

④下面我们需要调用SensorManager的registerListener()方法来注册SensorEventListener才能使其生效,registerListener()方法接收3个参数,第一个参数就是SensorEventListener的实例,第一个参数是Sensor的实例,第三个参数是用于表示传感器输出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST这四种值可选,其更新速率依次递增!

sensorManager.registerListener(listener,sensor,SensorManager.SENSOR_DELAY_GAME);

⑤当程序退出或传感器使用完毕时,一定要调用方法unregisterListener()将其使用的资源释放掉:

@Overrideprotected void onDestroy() {super.onDestroy();if (sensorManager!=null){sensorManager.unregisterListener(listener);}}

注意: 
1. 加速度传感器输出的信息存放的values数组中有3个值,分别代表手机在X轴,Y轴和Z轴方向上的加速度信息。由于地心引力的存在,手机都会有一个重力加速度9.8m/s²。当手机平放时,这个加速度作用在Z轴上,竖立时,这个加速度作用在Y轴上,当手机横立时,这个加速度作用在X轴。 
2. 方向传感器,Sensor.TYPE_ORIENTATION,它输出的值在values数组中,values[0]记录手机围绕Z轴的旋转角度,values[1]记录手机围绕X轴的旋转角度,values[2]记录手机围绕Y轴的旋转角度。但是Android早已废弃了Sensor.TYPE_ORIENTATION这种传感器类型,而是通过加速度传感器和地磁传感器共同计算得出。

简易指南针的展示

上边提到方向传感器已经由加速度传感器和地磁传感器共同计算替代。下面是具体的用法:

用法

①首先分别获得加速度传感器和地磁传感器的实例,并给它们注册监听器:

Sensor magneticSensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Sensor accelerometerSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(listener,magneticSensor,SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener,accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);

②接下来再onSensorChanged()方法中可以获取到SensorEvent的values数组,分别记录着加速度传感器和地磁传感器的值。然后将这两个值传入到SensorManager的getRotationMatrix()方法中就可以得到一个包含旋转矩阵的R数组。

SensorManager.getOrientation(R,values);

values是一个长度为3的float数组,其中values[0]记录手机围绕Z轴的 旋转弧度 ,values[1]记录手机围绕X轴的 旋转弧度 ,values[2]记录手机围绕Y轴的 旋转弧度 。 
注意这里计算出的数据是弧度,如果要转换为角度,则调用下面方法:

Math.toDegrees(values[0])

values[0]的取值范围是-180°到180°,其中±180°表示正南方向,0°表示正北方向,-90°表示正西方向,90°表示正东方向。

源码:

我们自己画一个简单的指南针MyCompassView,继承SurfaceView

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;/*** Created by Administrator on 2015/9/21.*/
public class MyCompassView extends SurfaceView {private int width;private int height;private Paint paint_circle;private Paint paint_line;private Paint paint_text;private String[] direction = {"E","S", "W","N"};private float degree;private boolean isRunning=true;public void setDegree(float degree) {this.degree = degree;}public MyCompassView(Context context) {super(context);}public MyCompassView(Context context, AttributeSet attrs) {super(context, attrs);SurfaceHolder holder = getHolder();holder.addCallback(callback);paint_circle = new Paint();paint_circle.setColor(Color.rgb(197, 194, 186));//画笔颜色paint_circle.setStrokeWidth(20);//画笔粗细paint_circle.setStyle(Paint.Style.STROKE);//空心paint_circle.setAntiAlias(true);//设置抗锯齿paint_line = new Paint();paint_line.setColor(Color.RED);paint_line.setStrokeWidth(15);paint_line.setAntiAlias(true);paint_text = new Paint();paint_text.setColor(Color.YELLOW);paint_text.setTextSize(50);paint_text.setAntiAlias(true);paint_text.setTextAlign(Paint.Align.CENTER);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);setMeasuredDimension(width, height);}SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(final SurfaceHolder holder) {//此处开启线程new Thread(new Runnable() {@Overridepublic void run() {while (isRunning) {Canvas canvas = holder.lockCanvas();canvas.drawColor(Color.rgb(65, 64, 61));canvas.drawCircle(width / 2, height / 2, 300, paint_circle);canvas.save();canvas.rotate(degree, width / 2, height / 2);for (int i = 1; i <= 4; i++) {canvas.save();canvas.rotate(360 / 4 * i, width / 2, height / 2);canvas.drawText(direction[i - 1], width / 2, height / 2 - 250, paint_text);canvas.restore();}canvas.drawCircle(width / 2, height / 2, 50, paint_line);Path path=new Path();path.moveTo(width/2-50,height/2);path.lineTo(width/2+50,height/2);path.lineTo(width/2,height/2-200);path.close();canvas.drawPath(path,paint_line);canvas.drawText(-(int)(degree)+"°",width/2,height/2,paint_text);canvas.restore();holder.unlockCanvasAndPost(canvas);}}}).start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {holder.setFixedSize(width,height);}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {//关闭线程isRunning=false;}};
}

然后加入到我们的布局中:

<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"tools:context=".MainActivity"><com.example.administrator.mycompass.MyCompassViewandroid:id="@+id/mycompassview"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"/></RelativeLayout>

最后是我们主活动中的代码:

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;public class MainActivity extends AppCompatActivity {private SensorManager sensorManager;private MyCompassView myCompassView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myCompassView= (MyCompassView) findViewById(R.id.mycompassview);sensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);Sensor magneticSensor=sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);Sensor accelerometerSensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(listener,magneticSensor,SensorManager.SENSOR_DELAY_GAME);sensorManager.registerListener(listener,accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected 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];@Overridepublic 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();}float[] R=new float[9];float[] values=new float[3];SensorManager.getRotationMatrix(R,null,accelerometerValues,magneticValues);SensorManager.getOrientation(R,values);float degree= -(float) Math.toDegrees(values[0]);//旋转角度myCompassView.setDegree(degree);}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};
}

Android传感器的使用开发、简易指南针相关推荐

  1. Android学习笔记-传感器开发之利用传感器和Tween开发简易指南针

    本次我们学习Android传感器的开发,前面已经介绍过了,tween的使用,所以,我们可以结合传感器与tween动画,开发简易的指南针. 首先先介绍一下传感器的相关知识, 在Android应用程序中使 ...

  2. Android传感器Motion Sensor开发实验

    目录 一.实验目的 二.实验要求 三.实验原理 (一)第一次实验 1.JDK(Java Development Kit) 2.Android SDK 3.AVD(Android Virtual Dev ...

  3. android 传感器使用与开发----光线传感器

    光线传感器的类型常量是Sensor.TYPE_LIGHT.values数组只有第一个元素(values[0])有意义.表示光线的强度.最大的值是120000.0f Android SDK将光线强度分为 ...

  4. Android 传感器开发详解

    Android 传感器开发详解 本文转载自:https://blog.csdn.net/airsaid/article/details/52902299 前言 使用 第一步 第二步 第三步 方向传感器 ...

  5. Android项目开发:指南针(两种方法实现)

    Android项目开发:指南针应用的实现 1.基于方向传感器 activity_main.xml MainActivity.java 2.基于加速度传感器和地磁传感器 在Android中可以使用内置传 ...

  6. 《Android传感器开发与智能设备案例实战》——导读

    本节书摘来自异步社区<Android传感器开发与智能设备案例实战>一书中的目录,作者 朱元波,更多章节内容可以访问云栖社区"异步社区"公众号查看 目 录 前 言 第1章 ...

  7. 《Android传感器开发与智能设备案例实战》——第2章,第2.4节安装ADT

    本节书摘来自异步社区<Android传感器开发与智能设备案例实战>一书中的第2章,第2.4节安装ADT,作者 朱元波,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  8. 《Android传感器开发与智能设备案例实战》——第1章,第1.2节Android的巨大优势...

    本节书摘来自异步社区<Android传感器开发与智能设备案例实战>一书中的第1章,第1.2节Android的巨大优势,作者 朱元波,更多章节内容可以访问云栖社区"异步社区&quo ...

  9. Android开发简易教程

    Android开发简易教程 Android 开发因为涉及到代码编辑.UI 布局.打包等工序,有一款好用的IDE非常重要.Google 最早提供了基于 Eclipse 的 ADT 作为开发工具,后来在2 ...

最新文章

  1. 嵌入式Linux的特点
  2. vivado----fpga硬件调试 (四)----mark_debug
  3. Java数据结构与算法之排序
  4. SilverLight学习笔记--建立Silverlight自定义控件(1)--外观设计
  5. 双层json报文样例_json报文解析
  6. 95-140-128-源码-transform-算子maxMin
  7. c++ lua 可以做什么_目前没成本有什么可以做
  8. 认知无线电切换算法,基于排队论源码
  9. 西数480G绿盘SSD搬板,SM2258xt开卡成功,附量产工具
  10. 教师计算机西沃培训心得,希沃电子白板学习心得体会
  11. IBM服务器无法启动怎么恢复
  12. 基于虚拟机的VxWorks实验平台设计与实现(读研时的一篇论文)
  13. 我的世界里 有你还不知道的秘密 边走边学习 且行且珍惜吧
  14. matlab画红色爱心(心形图)
  15. ULN2803驱动模块的使用
  16. 前端关于自己模拟接口做测试
  17. RTKLIB学习总结(三)RTKGET、RTKCONV、RTKPLOT、RTKPOST、STRSVR的使用
  18. 关于python中的+、+=、*、*=
  19. LibXL库使用详解
  20. 实验一 顺序与选择结构(Python 头歌)

热门文章

  1. Qt编写可视化大屏电子看板系统1-布局方案
  2. 苹果承认iOS源代码泄露,对iOS 11.2.5的有没有影响
  3. CentOS8 tingzhuxuan 不在 sudoers 文件中。此事将被报告。
  4. java jcr_java – 通过JCR实现基于标签的搜索系统的最佳方式,如Modeshape
  5. 【杂货铺】中国房屋种类
  6. 二进制里的「逢二进一」是什么意思
  7. linux根分区写保护,目录写保护,求助大神
  8. 程序员女装大佬们,你们太可怕了,我还以为在逛 PornHub 呢
  9. java 搭建个人博客_5分钟 教大家搭建免费个人博客
  10. 2018面试的-5分钟自我介绍建议