• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android 水准仪的实现(方向传感器的使用)

android 水准仪的实现(方向传感器的使用)

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android方向传感器,android传感器,android传感器开发,android 加速度传感器,android传感器编程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android 水准仪的实现(方向传感器的使用)


好久之前就已经研究了方向传感器Sensor.TYPE_ORIENTATION。根据自已实践,改写了网上的两个水准仪的例子,又重新封装使用了一下,最后也用在了项目中。

1、前言介绍

下面这段话是出自Android 传感器之方向传感器

 

一般情况下,在android系统中获取手机的方位信息在api中有TYPE_ORIENTATION常量,可以像得到加速度传感器那样得到方向传感器sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);然而我们这样做的话在最新版的SDK中就会看到这么一句话:“TYPE_ORIENTATIONThis constant is deprecated. use SensorManager.getOrientation() instead. ”即这种方式也过期,不建议使用!Google建议我们在应用程序中使用SensorManager.getOrientation()来获得原始数据。

 

public static float[] getOrientation (float[] R, float[] values)

第一个参数是R[] 是一个旋转矩阵,用来保存磁场和加速度的数据,可以理解为这个函数的传入值,通过它这个函数给你求出方位角。

第二个参数就是这个函数的输出了,他有函数自动为我们填充,这就是我们想要的。

 

values[0]:方向角,但用(磁场+加速度)得到的数据范围是(-180~180),也就是说,0表示正北,90表示正东,180/-180表示正南,-90表示正西。而直接通过方向感应器数据范围是(0~359)360/0表示正北,90表示正东,180表示正南,270表示正西。

values[1]pitch 倾斜角即由静止状态开始,前后翻转,手机顶部往上抬起(0~-90),手机尾部往上抬起(0~90)

values[2] roll旋转角即由静止状态开始,左右翻转,手机左侧抬起(0~90),手机右侧抬起(0~-90)

2、示例代码一

 

package com.level.level1;

import com.level.level1.R;

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 LevelView extends View
{
	// 定义水平仪大圆盘图片
	Bitmap compass;
	// 定义水平仪中的气泡图标
	Bitmap ball;
	// 定义水平仪中气泡 的X、Y座标
	int ballX, ballY;
	
	// 定义气泡位于中间时(水平仪完全水平),气泡的X、Y座标
	int cx, cy;
	// 定义水平仪大圆盘中心座标X、Y
	int backCx;
	int backCy;
	// 定义灵敏度,即水平仪能处理的最大倾斜角,超过该角度,气泡将直接在位于边界。
	int SENSITIVITY = 30;

	public LevelView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		// 加载水平仪大圆盘图片和气泡图片
		compass = BitmapFactory.decodeResource(getResources()
			, R.drawable.back);
		ball = BitmapFactory
			.decodeResource(getResources(), R.drawable.small);
		
		
		// 计算出 水平仪完全水平时 气泡位置  左上角为原点
		cx = (compass.getWidth() - ball.getWidth()) / 2;
		cy = (compass.getHeight() - ball.getHeight()) / 2;

		// 计算出水平仪大圆盘中心座标X、Y  左上角为原点
		backCx = compass.getWidth() / 2;
		backCy = compass.getWidth() / 2;
	}

	@Override
	protected void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);
		// 绘制水平仪大圆盘图片
		canvas.drawBitmap(compass, 0, 0, null);
		// 根据气泡坐标绘制气泡
		canvas.drawBitmap(ball, ballX, ballY, null);
	}
	
	public void onChangeXY(int zAngle,int yAngle,int xAngle){
		// 定义气泡当前位置X Y坐标值
		int x, y;
		x = cx;
		y = cy;
		
		// 如果沿x轴的倾斜角  在最大角度之内则计算出其相应坐标值
		if (Math.abs(xAngle) <= SENSITIVITY) {
			// 根据与x轴的倾斜角度计算X座标的变化值(倾斜角度越大,X座标变化越大)
			int deltaX = (int) (cx * xAngle / SENSITIVITY);
			x += deltaX;
		}
		// 如果沿x轴的倾斜角已经大于MAX_ANGLE,气泡应到最左边
		else if (xAngle > SENSITIVITY) {
			x = 0;
		}
		// 如果与x轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
		else {
			x = cx * 2;
		}
		// 如果沿Y轴的倾斜角还在最大角度之内
		if (Math.abs(yAngle) <= SENSITIVITY) {
			// 根据沿Y轴的倾斜角度计算Y座标的变化值(倾斜角度越大,Y座标变化越大)
			int deltaY = (int) (cy * yAngle / SENSITIVITY);
			y += deltaY;
		}
		// 如果沿Y轴的倾斜角已经大于MAX_ANGLE,气泡应到最下边
		else if (yAngle > SENSITIVITY) {
			y = cy * 2;
		}
		// 如果沿Y轴的倾斜角已经小于负的MAX_ANGLE,气泡应到最右边
		else {
			y = 0;
		}
		// 如果计算出来的X、Y座标还位于水平仪的仪表盘内,更新水平仪的气泡座标
		if (isContain(x, y)) {
			ballX = x;
			ballY = y;
		} else {
			// 有待后续继续完成
		}
		//重绘界面
		invalidate();
	}
	
	// 计算x、y点的气泡是否处于水平仪的大圆盘内
	private boolean isContain(int x, int y) {
		// 计算气泡的圆心座标X、Y
		int ballCx = x + ball.getWidth() / 2;
		int ballCy = y + ball.getWidth() / 2;

		// 计算气泡的圆心与水平仪大圆盘中中心之间的距离。
		double distance = Math.sqrt((ballCx - backCx) * (ballCx - backCx)
				+ (ballCy - backCy) * (ballCy - backCy));
		// 若两个圆心的距离小于它们的半径差,即可认为处于该点的气泡依然位于仪表盘内
		if (distance < cx) {
			return true;
		} else {
			return false;
		}
	}
}

package com.level.level1;

import com.level.level1.R;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;

public class MyGradienter extends Activity implements SensorEventListener {
	// 定义水平仪的仪大圆盘
	private LevelView myview;
	// 定义Sensor管理器
	SensorManager mySM;
	// 定义显示栏 显示X Y Z轴方向转过角度与当前方位
	private TextView tx, ty, tz, td;
	private Sensor acc_sensor;
	private Sensor mag_sensor;
	// 加速度传感器数据
	float accValues[] = new float[3];
	// 地磁传感器数据
	float magValues[] = new float[3];
	// 旋转矩阵,用来保存磁场和加速度的数据
	float r[] = new float[9];
	// 模拟方向传感器的数据(原始数据为弧度)
	float values[] = new float[3];

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_gradienter);
		myview = (LevelView) findViewById(R.id.myview);
		tx = (TextView) findViewById(R.id.testviewx);
		ty = (TextView) findViewById(R.id.testviewy);
		tz = (TextView) findViewById(R.id.testviewz);
		td = (TextView) findViewById(R.id.testviewd);
		// 获取手机传感器管理服务
		mySM = (SensorManager) getSystemService(SENSOR_SERVICE);
	}

	@Override
	public void onResume() {
		super.onResume();

		acc_sensor = mySM.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		mag_sensor = mySM.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
		// 给传感器注册监听:
		mySM.registerListener(this, acc_sensor, SensorManager.SENSOR_DELAY_GAME);
		mySM.registerListener(this, mag_sensor, SensorManager.SENSOR_DELAY_GAME);
	}

	@Override
	protected void onPause() {
		// 取消方向传感器的监听
		mySM.unregisterListener(this);
		super.onPause();
	}

	@Override
	protected void onStop() {
		// 取消方向传感器的监听
		mySM.unregisterListener(this);
		super.onStop();
	}

	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		// 获取手机触发event的传感器的类型
		int sensorType = event.sensor.getType();
		switch (sensorType) {
		case Sensor.TYPE_ACCELEROMETER:
			accValues = event.values.clone();
			break;
		case Sensor.TYPE_MAGNETIC_FIELD:
			magValues = event.values.clone();
			break;

		}

		SensorManager.getRotationMatrix(r, null, accValues, magValues);
		SensorManager.getOrientation(r, values);

		// 获取 沿着Z轴转过的角度
		int zAngle = (int) Math.toDegrees(values[0]);
		tz.setText("Z轴方向转过的角度:" + zAngle);
		// 显示当前的方位
		displayCompass(zAngle);

		// 获取 沿着X轴倾斜时 与Y轴的夹角
		int yAngle = (int) Math.toDegrees(values[1]);
		ty.setText("Y轴方向翘起的角度:" + yAngle);

		// 获取 沿着Y轴的滚动时 与X轴的角度
		int xAngle = (int) Math.toDegrees(values[2]);
		tx.setText("x轴方向翘起的角度:" + xAngle);
		
		myview.onChangeXY(zAngle,yAngle,xAngle);
	}

	private void displayCompass(int angle) {
		if ((angle < 22.5) || (angle > 337.5))
			td.setText("手机顶部当前方位: 北");
		if ((a



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • android 水准仪的实现(方向传感器的使用)

相关文章

  • 2017-05-26阅读《Android 从入门到精通》(29)——LinearLayout 等四类方法
  • 2018-01-28android 滑动冲突的处理
  • 2017-05-26android开发之路01,android之路01
  • 2017-05-26Android 面试题--Service,android--service
  • 2017-05-26Android必知必会-使用okhttp的PUT方式上传文件
  • 2017-05-26我的android学习经历9,android学习经历9
  • 2017-05-26Android 实用代码片段,
  • 2017-05-26历代安卓版本回顾(使用者角度+开发者角度)长期更新!!!,安卓开发者
  • 2017-05-26xshell可以ping通但是不能远程服务器,putty可以远程
  • 2017-05-26onSaveInstanceState和onRestoreInstanceState触发的时机,onsaveinstancestate

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Mobizen免帐号版,Mobizen帐号版
    • ListView和Adapter的配合使用以及Adapter的重写,listviewadapter
    • Adapter模式实战-重构鸿洋的Android建行圆形菜单
    • 自定义图片轮播,简单就是好用,自定义图片轮播
    • Android之侧滑导航栏,android滑导航栏
    • Android便携式热点的开启状态检测和SSID的获取,android热点ssid
    • 微博API常用方法,博API常用方法
    • React-Native系列Android——Native与Javascript通信原理(二)
    • HBase Java编程示例
    • Mac搭建Android开发环境,mac搭建android

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有