阅读郭霖《第一行代码》的笔记——第12章 Android特色开发,使用传感器

本文主要是介绍阅读郭霖《第一行代码》的笔记——第12章 Android特色开发,使用传感器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、传感器简介

手机中内置的传感器是一种微型的物理设备,它能够探测、感受到外界的信号,并按一定规律转换成我们所需要的信息。Android手机通常都会支持多种类型的传感器,如光照传感右器、加速度传感器、地磁传感器、压力传感器、温度传感器等。
当然,Android系统只是负责将这些传感器所输出的信息传递给我们,至于具体如何去利用这些信息就要充分发挥开发者的想象力了。目前市场上很多的程序都有使用到传感器的功能,比如最常见的赛车游戏,玩家可以通过旋转设备来控制赛车的前进方向,就像是在操作方向盘一样。除此之外,微信的摇一摇功能,手机指南针等软件也都是借助传感器来完成的。

2、光照传感器

光照传感器在Android中的应用还是比较常见的,比如系统就有个自动调整屏幕亮度的功能。它会检测手机周围环境的光照强度,然后对手机屏幕的亮度进行相应地调整,以此保证不管是在强光还是弱光下,手机屏幕都能够看得清。
例子:
布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/txt_light_lever"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="1"android:textSize="20sp" /></RelativeLayout>

代码:

package com.example.test.sensor;import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;import com.example.test.R;/**
* Created by Administrator on 2016/6/4.
*/
public class LightSensorActivity extends Activity {private TextView txtLevel;//SensorManager是系统所有传感器的管理器,有了它的实例之后就可以调用getDefaultSensor()方法来得到任意的传感器类型了private SensorManager sensorManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sensor_light);txtLevel = (TextView) findViewById(R.id.txt_light_lever);sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);//这里使用Sensor.TYPE_LIGHT常量来指定传感器类型,此时的Sensor实例就代表着一个光照传感器Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);/***调用SensorManager的registerListener()方法来注册SensorEventListener才能使其生效,registerListener()方法接收三个参数* 第一个参数就是SensorEventListener的实例,* 第二个参数是Sensor的实例,* 第三个参数是用于表示传感器输出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、*        SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST这四种值可选,它们的更新速率是依次递增的。*/sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_NORMAL);}/*** 调用unregisterListener()方法来释放使用的资源*/@Overrideprotected void onDestroy() {super.onDestroy();if (null != sensorManager) {sensorManager.unregisterListener(listener);}}//SensorEventListener是对传感器输出的信号进行监听,SensorEventListener是一个接口,其中定义了onSensorChanged()和onAccuracyChanged()这两个方法private SensorEventListener listener = new SensorEventListener() {/*** 当传感器的精度发生变化时就会调用onAccuracyChanged()方法* @param event SensorEvent参数里又包含了一个values数组,所有传感器输出的信息都是存放在这里的。*/@Overridepublic void onSensorChanged(SensorEvent event) {//values数组中第一个下标的值就是当前的光照强度float value = event.values[0];txtLevel.setText("Current light level is " + value + " lx.");}/*** 当传感器监测到的数值发生变化时就会调用onSensorChanged()方法* @param sensor 传感器* @param accuracy 变化后的值*/@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};}

3、加速度传感器

Android中的加速度传感器则是提供了一种机制,使得我们能够在应用程序中获取到手机当前的加速度信息,合理利用这些信息就可以开发出一些比较好玩的功能。
接下来我们尝试利用加速度传感器来模仿一下微信的摇一摇功能。其实主体逻辑也非常简单,只需要检测手机在X轴、Y轴和Z轴上的加速度,当达到了预定值的时候就可以认为用户摇动了手机,从而触发摇一摇的逻辑。那么现在问题在于,这个预定值应该设定为多少呢?由于重力加速度的存在,即使手机在静止的情况下,某一个轴上的加速度也有可能达到9.8m/s2,因此这个预定值必定是要大于9.8m/s2的,这里我们就设定为15m/s2吧。
例子:
布局:什么都没有,

<?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"></LinearLayout>

代码:

package com.example.test.sensor;import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;import com.example.test.R;/**
* Created by Administrator on 2016/6/4.
*/
public class AccelerometerSensorActivity extends Activity {private SensorManager sensorManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sensor_accelerometer);sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_NORMAL);}@Overrideprotected void onDestroy() {super.onDestroy();if (null != sensorManager) {sensorManager.unregisterListener(listener);}}private SensorEventListener listener = new SensorEventListener() {@Overridepublic 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(AccelerometerSensorActivity.this, "摇一摇", Toast.LENGTH_SHORT).show();}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};}

#4、方向传感器

要说Android中另外一个比较常用的传感器应该就是方向传感器了。方向传感器的使用场景要比其他的传感器更为广泛,它能够准确地判断出手机在各个方向的旋转角度,利用这些角度就可以编写出像指南针、地平仪等有用的工具。另外,在本章开始时介绍的通过旋转设备来控制方向的赛车游戏,也是使用方向传感器来完成的。Android获取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算得出的,这也是Android目前推荐使用的方式。
例子:制作简易指南针
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/img_compass"android:layout_width="250dp"android:layout_height="250dp"android:layout_centerInParent="true"android:src="@drawable/compass" /><ImageViewandroid:layout_width="60dp"android:layout_height="110dp"android:layout_centerInParent="true"android:src="@drawable/arrow" /></RelativeLayout>

主界面:

package com.example.compasstest;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.v7.app.AppCompatActivity;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private SensorManager sensorManager;//指南针的背景图private ImageView imgCompass;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imgCompass = (ImageView) findViewById(R.id.img_compass);sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//获取加速传感器,并为它注册监听器Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);sensorManager.registerListener(listener, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME);//获取地磁传感器,并为它注册监听器Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);sensorManager.registerListener(listener, magneticSensor, SensorManager.SENSOR_DELAY_GAME);//注:SensorManager.SENSOR_DELAY_GAME为传感器输出信息的更新速度}private SensorEventListener listener = new SensorEventListener() {float[] accelerometerValues = new float[3];float[] magneticValues = new float[3];private float lastRotateDegree;@Overridepublic void onSensorChanged(SensorEvent event) {//判断当前是加速传感器还是地磁传感器if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {//注意赋值的时候要调用close方法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);//values[0]表示是手机围绕Z轴旋转的弧度,Math.toDegrees()方法是将弧度转化成角度
//            Log.i(TAG, "values[0] is " + Math.toDegrees(values[0]));//values[0]的取值范围是-180度到180度,其中±180度表示正南方向,0度表示正北方向,90度表示正西方向,90度表示正东方向。//将计算出的旋转角度取反,用于旋转指南针背景图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);//执行旋转动画imgCompass.startAnimation(animation);lastRotateDegree = rotateDegree;}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};@Overrideprotected void onDestroy() {super.onDestroy();if (null!=sensorManager){sensorManager.unregisterListener(listener);}}}

主题设置:
在AndroidManifest文件里面种application里面的属性theme设置值为@style/AppTheme,而AppTheme里面设置

   <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"><item name="android:windowActionBar">false</item><!--<item name="windowActionBar">false</item>--></style>

效果图:
指南针
当然了,Android中支持的传感器远远不只这些,还有压力传感器、温度传感器、陀螺仪传感器等,不过由于这些传感器都不太常用,而且不少Android手机中都没有嵌入这些传感器。

这篇关于阅读郭霖《第一行代码》的笔记——第12章 Android特色开发,使用传感器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/371663

相关文章

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

Python实现文件下载、Cookie以及重定向的方法代码

《Python实现文件下载、Cookie以及重定向的方法代码》本文主要介绍了如何使用Python的requests模块进行网络请求操作,涵盖了从文件下载、Cookie处理到重定向与历史请求等多个方面,... 目录前言一、下载网络文件(一)基本步骤(二)分段下载大文件(三)常见问题二、requests模块处理

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

vscode保存代码时自动eslint格式化图文教程

《vscode保存代码时自动eslint格式化图文教程》:本文主要介绍vscode保存代码时自动eslint格式化的相关资料,包括打开设置文件并复制特定内容,文中通过代码介绍的非常详细,需要的朋友... 目录1、点击设置2、选择远程--->点击右上角打开设置3、会弹出settings.json文件,将以下内

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫