Android利用Sensor(传感器)实现水平仪功能

这里介绍的水平仪,指的是比较传统的气泡水平仪,在一个透明圆盘内充满液体,液体中留有一个气泡,当一端翘起时,该气泡就会浮向翘起的一端。

利用方向传感器返回的第一个参数,实现了一个指南针小应用。

我的Android进阶之旅------>Android利用Sensor(传感器)实现指南针功能

接下来,我们利用返回的第二、三个参数实现该水平仪。因为第二个参数,反映底部翘起的角度(当顶部翘起时为负值),第三个参数可以反映右侧翘起的角度(当左侧翘起时为负值)。根据这两个角度就可以开发水平仪,实现手机哪端翘起,气泡就浮向哪端,这也是水平仪的实现思想。本实例来自于《疯狂Android讲义》

先来看下运行效果:

该程序自定义了一个View,用来绘制透明圆盘和气泡,其中气泡的位置会动态改变。自定义View代码如下:

MyView.java

package org.crazyit.sensor; 

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View; 

public class MyView extends View {
 // 定义水平仪仪表盘图片
 Bitmap back;
 // 定义水平仪中的气泡图标
 Bitmap bubble;
 // 定义水平仪中气泡 的X、Y座标
 int bubbleX, bubbleY; 

 public MyView(Context context, AttributeSet attrs) {
 super(context, attrs);
 // 加载水平仪图片和气泡图片
 back = BitmapFactory.decodeResource(getResources(), R.drawable.back);
 bubble = BitmapFactory
 .decodeResource(getResources(), R.drawable.bubble);
 } 

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 // 绘制水平仪表盘图片
 canvas.drawBitmap(back, 0, 0, null);
 // 根据气泡座标绘制气泡
 canvas.drawBitmap(bubble, bubbleX, bubbleY, null);
 }
} 

布局文件 main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="#fff"
 >
<org.crazyit.sensor.MyView
 android:id="@+id/show"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
/>
</FrameLayout>

素材:

bubble.png:

back.png :

Gradienter.java

package org.crazyit.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; 

public class Gradienter extends Activity implements SensorEventListener {
 // 定义水平仪的仪表盘
 MyView show;
 // 定义水平仪能处理的最大倾斜角,超过该角度,气泡将直接在位于边界。
 int MAX_ANGLE = 30;
 // 定义Sensor管理器
 SensorManager mSensorManager; 

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 // 获取水平仪的主组件
 show = (MyView) findViewById(R.id.show);
 // 获取传感器管理服务
 mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
 } 

 @Override
 public void onResume() {
 super.onResume();
 // 为系统的方向传感器注册监听器
 mSensorManager.registerListener(this,
 mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
 SensorManager.SENSOR_DELAY_GAME);
 } 

 @Override
 protected void onPause() {
 // 取消注册
 mSensorManager.unregisterListener(this);
 super.onPause();
 } 

 @Override
 protected void onStop() {
 // 取消注册
 mSensorManager.unregisterListener(this);
 super.onStop();
 } 

 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 } 

 @Override
 public void onSensorChanged(SensorEvent event) {
 float[] values = event.values;
 // 获取触发event的传感器类型
 int sensorType = event.sensor.getType();
 switch (sensorType) {
 case Sensor.TYPE_ORIENTATION:
 // 获取与Y轴的夹角
 float yAngle = values[1];
 // 获取与Z轴的夹角
 float zAngle = values[2];
 // 气泡位于中间时(水平仪完全水平),气泡的X、Y座标
 int x = (show.back.getWidth() - show.bubble.getWidth()) / 2;
 int y = (show.back.getHeight() - show.bubble.getHeight()) / 2;
 // 如果与Z轴的倾斜角还在最大角度之内
 if (Math.abs(zAngle) <= MAX_ANGLE) {
 // 根据与Z轴的倾斜角度计算X座标的变化值(倾斜角度越大,X座标变化越大)
 int deltaX = (int) ((show.back.getWidth() - show.bubble
  .getWidth()) / 2 * zAngle / MAX_ANGLE);
 x += deltaX;
 }
 // 如果与Z轴的倾斜角已经大于MAX_ANGLE,气泡应到最左边
 else if (zAngle > MAX_ANGLE) {
 x = 0;
 }
 // 如果与Z轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
 else {
 x = show.back.getWidth() - show.bubble.getWidth();
 }
 // 如果与Y轴的倾斜角还在最大角度之内
 if (Math.abs(yAngle) <= MAX_ANGLE) {
 // 根据与Y轴的倾斜角度计算Y座标的变化值(倾斜角度越大,Y座标变化越大)
 int deltaY = (int) ((show.back.getHeight() - show.bubble
  .getHeight()) / 2 * yAngle / MAX_ANGLE);
 y += deltaY;
 }
 // 如果与Y轴的倾斜角已经大于MAX_ANGLE,气泡应到最下边
 else if (yAngle > MAX_ANGLE) {
 y = show.back.getHeight() - show.bubble.getHeight();
 }
 // 如果与Y轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
 else {
 y = 0;
 }
 // 如果计算出来的X、Y座标还位于水平仪的仪表盘内,更新水平仪的气泡座标
 if (isContain(x, y)) {
 show.bubbleX = x;
 show.bubbleY = y;
 }
 // 通知系统重回MyView组件
 show.postInvalidate();
 break;
 }
 } 

 // 计算x、y点的气泡是否处于水平仪的仪表盘内
 private boolean isContain(int x, int y) {
 // 计算气泡的圆心座标X、Y
 int bubbleCx = x + show.bubble.getWidth() / 2;
 int bubbleCy = y + show.bubble.getWidth() / 2;
 // 计算水平仪仪表盘的圆心座标X、Y
 int backCx = show.back.getWidth() / 2;
 int backCy = show.back.getWidth() / 2;
 // 计算气泡的圆心与水平仪仪表盘的圆心之间的距离。
 double distance = Math.sqrt((bubbleCx - backCx) * (bubbleCx - backCx)
 + (bubbleCy - backCy) * (bubbleCy - backCy));
 // 若两个圆心的距离小于它们的半径差,即可认为处于该点的气泡依然位于仪表盘内
 if (distance < (show.back.getWidth() - show.bubble.getWidth()) / 2) {
 return true;
 } else {
 return false;
 }
 }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="org.crazyit.sensor"
 android:versionCode="1"
 android:versionName="1.0">
 <uses-sdk
 android:minSdkVersion="10"
 android:targetSdkVersion="17" />
 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
 <activity android:name=".Gradienter"
 android:label="@string/app_name">
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 </application>
</manifest> 

PS:请在真机环境下运行此程序,如果在模拟器下运行,可能没效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们

(0)

相关推荐

  • Android编程实现获取所有传感器数据的方法

    本文实例讲述了Android编程实现获取所有传感器数据的方法.分享给大家供大家参考,具体如下: main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" androi

  • Android利用传感器实现微信摇一摇功能

    本文实例为大家分享了Android微信摇一摇功能的实现方法,供大家参考,具体内容如下 import java.util.ArrayList; import java.util.List; import java.util.Random; import android.app.Activity; import android.app.Service; import android.content.res.Resources; import android.hardware.Sensor; impo

  • Android操作系统介绍之11种传感器

    Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发.接下来通过本文给大家介绍Android操作系统介绍之11种传感器. 在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用. #define SENSOR_TYPE_ACCELEROMETER 1 //加速度 #define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力 #define

  • Android利用Sensor(传感器)实现指南针小功能

    首先来说一说该指南针的实现思路: 程序先准备一张指南针图片,该图片上方向指针指向北方.接下来开发一个检测方向的传感器,程序检测到手机顶部绕Z轴转过多少度,让指南针图片反向转多少度即可.由此可见指南针应用只要在界面中添加一张图片,并让图片总是反向转过反向传感器返回的第一个角度值即可. 下面介绍一下方向传感器:方向传感器用于感应手机设备的摆放状态.方向传感器可以返回三个角度,这三个角度即可确定手机的摆放状态.关于方向传感器返回的三个角度的说明如下. 第一个角度:表示手机顶部朝向正北方的夹角.当手机绕

  • Android利用方向传感器获得手机的相对角度实例说明

    1.android 的坐标系是如何定义x, y z 轴的 x轴的方向是沿着屏幕的水平方向从左向右,如果手机不是正方形的话,较短的边需要水平放置,较长的边需要垂直放置. Y轴的方向是从屏幕的左下角开始沿着屏幕的的垂直方向指向屏幕的顶端. 将手机放在桌子上,z轴的方向是从手机指向天空. 2.方向传感器 在方向传感器中values变量的3个值都表示度数,它们的含义如下: values[0]:该值表示方位,也就是手机绕着Z轴旋转的角度.0表示北(North):90表示东(East):180表示南(Sou

  • Android 获取传感器列表整理及简单实例

    Android 获取传感器列表整理及简单实例 Android 4.4 (API等级19)支持以下传感器: TYPE_ACCELEROMETER 加速度传感器,单位是m/s2,测量应用于设备X.Y.Z轴上的加速度 传感器类型值(Sensor Type):1 (0x00000001) TYPE_AMBIENT_TEMPERATURE 温度传感器,单位是℃ 传感器类型值(Sensor Type): 13 (0x0000000d) TYPE_GAME_ROTATION_VECTOR 游戏动作传感器,不收

  • Android开发获取传感器数据的方法示例【加速度传感器,磁场传感器,光线传感器,方向传感器】

    本文实例讲述了Android开发获取传感器数据的方法.分享给大家供大家参考,具体如下: package mobile.android.sensor; import java.util.List; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import an

  • Android 重力传感器在游戏开发中的应用

    手势操作可以说是智能手机的一种魅力所在,前两节给大家讲解了两种有趣的手势操作,将它们置于游戏当中,大大提升了游戏的可玩性和趣味性.本节将继续介绍智能手机的另一种神奇之处:传感器.    一.何为传感器 所谓传感器就是能够探测如光.热.温度.重力.方向等等的装置.    二.Android提供了哪些传感器 1.加速度传感器(重力传感器) 2.陀螺仪传感器 3.光传感器 4.恒定磁场传感器 5.方向传感器 6.恒定的压力传感器 7.接近传感器 8.温度传感器 今天我们给大家介绍的是游戏开发中最最常见

  • Android利用传感器仿微信摇一摇功能

    传感器 简单的介绍一下传感器: 就是设备用来感知周边环境变化的硬件. Android中的传感器包含在传感器框架中,属于android.hardware.*(硬件部分) 传感器框架主要包含四个部分: ① SensorManager:用来获取传感器的入口,它是一个系统的服务,还可以为传感器注册与取消注册监听 ② Sensor: 具体的传感器,包含了传感器的名字,类型,采样率 ③ SensorEvent:传感器事件,包含了传感器采集回来的数据,传感器的精度 ④ SensorEventListener:

  • Android 传感器--光照传感器详解及使用

    Android 设备中有许多传感器,其中有一个传感器控制着你屏幕亮度的变化.当你在很暗的地方使用手机,你设备的屏幕会自动调暗,从而保护你眼睛. 起着这样作用,Android是通过一款光照传感器来获取你周围环境亮度的变化.光照传感器一般在手机的顶部的位置. 要在程序中使用这款传感器 (1)首先要获取SensorManager传感器管理器服务:SensorManager sensorManager=(SensorManager)getSystemService(Context.SENSOR_SERV

  • Android重力传感器实现滚动的弹球

    熟知: 什么是传感器: 所谓传感器能够探测如光.热.温度.重力.方向 等等的功能! Android中提供传感器有哪些: 1.  加速度传感器(重力传感器)      2.  陀螺仪传感器      3.  光传感器      5.  恒定磁场传感器      6.  方向传感器      7.  恒定的压力传感器      8.  接近传感器      9.  温度传感器 一. 问题描述 Android中有多达11种传感器,不同的手机设备支持的传感器类型也不尽相同 1. 重力传感器 GV-sen

  • android 传感器(OnSensorChanged)使用介绍

    下面是API中定义的几个代表sensor的常量. Int TYPE_ACCELEROMETER A constant describing an accelerometer sensor type. 加速度传感器 int TYPE_ALL A constant describing all sensor types. 所有类型 A constant describing all sensor types. int TYPE_GRAVITY A constant describing a grav

随机推荐