在Android中可以使用内置传感器(方向传感器、加速度传感器和地磁传感器等)实现指南针功能,编写出能够辨别手机方位的app。本文将讲述两种方法编写指南针app的方法,一是使用方向传感器,二是将加速度传感器和地磁传感器结合。

文章目录

  • 一、方向传感器
  • 二、基于加速度传感器和地磁传感器
  • 三、页面布局
  • 总结

一、方向传感器

方向传感器是Android的基本传感器之一,通过三维坐标来确定(X,Y,Z)的三个方向,以进一步实现指南针功能,Sensor.TYPE_ORIENTATION在目前的Android系统中已经不再推荐使用,但是仍然可以通过其来获取数据。

实现代码(Activity):


//方向传感器指南针页面
public class CompassActivity1 extends AppCompatActivity  implements SensorEventListener {private ImageView iv_arrow;private TextView tv_orientation;private Context context;private SensorManager sensorManager;//private int  currentSensorType;//方向角度@Overrideprotected void onCreate( Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_layout_compactivity);iv_arrow = findViewById(R.id.iv_arrow);tv_orientation = findViewById(R.id.tv_orientation);context = CompassActivity1.this;sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);}@Overrideprotected void onResume() {super.onResume();//为方向传感器注册监听器List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);for (Sensor s : sensors) {sensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_FASTEST);}}@Overrideprotected void onPause() {super.onPause();sensorManager.unregisterListener(this);}//1、北,2东北,3东,4东南,5南,6西南,7西,8西北public void showLocationWithSensor(int type){if(type==currentSensorType){return;}currentSensorType = type;Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.iv_arrow), dip2px(context,40), dip2px(context,40),  true);int degrees=0;//旋转角度if(currentSensorType==1){degrees=0;tv_orientation.setText("北");}else  if(currentSensorType==2){degrees=45;tv_orientation.setText("东北");}else  if(currentSensorType==3){degrees=90;tv_orientation.setText("东");}else  if(currentSensorType==4){degrees=135;tv_orientation.setText("东南");}else  if(currentSensorType==5){degrees=180;tv_orientation.setText("南");}else  if(currentSensorType==6){degrees=-135;tv_orientation.setText("西南");}else  if(currentSensorType==7){degrees=-90;tv_orientation.setText("西");}else  if(currentSensorType==8){degrees=-45;tv_orientation.setText("西北");}Matrix matrix = new Matrix();matrix.postRotate(degrees);Bitmap newBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),  matrix, true);iv_arrow.setImageBitmap(newBmp);}@Overridepublic void onSensorChanged(SensorEvent event) {if(event.sensor.getType()==Sensor.TYPE_ORIENTATION){float degree = event.values[0];     //取围绕z轴转过的角度float azimuth = (degree + 360) % 360;if (azimuth <= 15 || azimuth >= 345) {showLocationWithSensor(1);} else if (15 < azimuth && azimuth < 75) {showLocationWithSensor(2);} else if (75 <= azimuth && azimuth <= 105) {showLocationWithSensor(3);} else if (105 < azimuth && azimuth < 165) {showLocationWithSensor(4);} else if (165 <= azimuth && azimuth <= 195) {showLocationWithSensor(5);} else if (195 < azimuth && azimuth < 255) {showLocationWithSensor(6);} else if (255 <= azimuth && azimuth <= 285) {showLocationWithSensor(7);} else if (285 < azimuth && azimuth < 345) {showLocationWithSensor(8);}}}@Overridepublic void onAccuracyChanged(Sensor sensor, int i) {}/*** dip转换px*/public static int dip2px(Context context, float dip) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dip * scale + 0.5f);}}

二、基于加速度传感器和地磁传感器

实现代码(Activity):


//基于加速度传感器和地磁传感器
public class CompassActivity2 extends AppCompatActivity  implements SensorEventListener {private ImageView iv_arrow;private TextView tv_orientation;private Context context;private SensorManager sensorManager;//private int  currentSensorType;//方向角度private float[] mGravity = new float[3];private float[] mGeomagnetic = new float[3];@Overrideprotected void onCreate( Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_layout_compactivity);iv_arrow = findViewById(R.id.iv_arrow);tv_orientation = findViewById(R.id.tv_orientation);context = CompassActivity2.this;sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);   //加速度感应器Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //地磁感应器sensorManager.registerListener(this, magneticSensor, SensorManager.SENSOR_DELAY_GAME);sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_GAME);}@Overrideprotected void onDestroy() {super.onDestroy();if (sensorManager != null) {sensorManager.unregisterListener(this);}}//1、北,2东北,3东,4东南,5南,6西南,7西,8西北public void showLocationWithSensor(int type){if(type==currentSensorType){return;}currentSensorType = type;Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.iv_arrow), dip2px(context,40), dip2px(context,40),  true);int degrees=0;//旋转角度if(currentSensorType==1){degrees=0;tv_orientation.setText("北");}else  if(currentSensorType==2){degrees=45;tv_orientation.setText("东北");}else  if(currentSensorType==3){degrees=90;tv_orientation.setText("东");}else  if(currentSensorType==4){degrees=135;tv_orientation.setText("东南");}else  if(currentSensorType==5){degrees=180;tv_orientation.setText("南");}else  if(currentSensorType==6){degrees=-135;tv_orientation.setText("西南");}else  if(currentSensorType==7){degrees=-90;tv_orientation.setText("西");}else  if(currentSensorType==8){degrees=-45;tv_orientation.setText("西北");}Matrix matrix = new Matrix();matrix.postRotate(degrees);Bitmap newBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),  matrix, true);iv_arrow.setImageBitmap(newBmp);}@Overridepublic void onSensorChanged(SensorEvent event) {final float alpha = 0.97f;synchronized (this) {//指南针转动角度算法//判断当前是加速度感应器还是地磁感应器if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {mGravity[0] = alpha * mGravity[0] + (1 - alpha)   * event.values[0];mGravity[1] = alpha * mGravity[1] + (1 - alpha)   * event.values[1];mGravity[2] = alpha * mGravity[2] + (1 - alpha)      * event.values[2];}if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {float[] values = event.values;mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha) * event.values[0];mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha) * event.values[1];mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha) * event.values[2];}float R[] = new float[9];float I[] = new float[9];boolean success = SensorManager.getRotationMatrix(R, I, mGravity,  mGeomagnetic);if (success) {float orientation[] = new float[3];SensorManager.getOrientation(R, orientation);float  azimuth = (float) Math.toDegrees(orientation[0]); // orientationazimuth = (azimuth + 360) % 360;if (azimuth <= 15 || azimuth >= 345) {showLocationWithSensor(1);} else if (15 < azimuth && azimuth < 75) {showLocationWithSensor(2);} else if (75 <= azimuth && azimuth <= 105) {showLocationWithSensor(3);} else if (105 < azimuth && azimuth < 165) {showLocationWithSensor(4);} else if (165 <= azimuth && azimuth <= 195) {showLocationWithSensor(5);} else if (195 < azimuth && azimuth < 255) {showLocationWithSensor(6);} else if (255 <= azimuth && azimuth <= 285) {showLocationWithSensor(7);} else if (285 < azimuth && azimuth < 345) {showLocationWithSensor(8);}}}}@Overridepublic void onAccuracyChanged(Sensor sensor, int i) {}/*** dip转换px*/public static int dip2px(Context context, float dip) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dip * scale + 0.5f);}}

三、页面布局

这两个页面使用的同一个xml布局文件。

实现代码(xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/layout_arrow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:orientation="horizontal"android:gravity="center"android:layout_centerVertical="true"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="西"android:textStyle="bold"android:textSize="22sp" /><ImageViewandroid:id="@+id/iv_arrow"android:layout_width="100dp"android:layout_height="100dp"android:layout_marginTop="10dp"android:src="@color/purple_500"android:layout_marginRight="10dp"android:layout_marginLeft="10dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="东"android:textStyle="bold"android:textSize="22sp"/></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="南"android:textStyle="bold"android:textSize="22sp"android:layout_centerHorizontal="true"android:layout_below="@id/layout_arrow"android:layout_marginTop="10dp"/><TextViewandroid:id="@+id/tv1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="北"android:textStyle="bold"android:textSize="22sp"android:layout_above="@id/layout_arrow"android:layout_centerHorizontal="true"/><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/layout_arrow"android:layout_marginTop="100dp"><TextViewandroid:id="@+id/tv_orientation"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="方位:东"android:textStyle="bold"android:textSize="22sp"android:layout_centerHorizontal="true"/></RelativeLayout></RelativeLayout>

总结

这两种方式都可以实现,不过方向传感器相对简单但是不提倡了。
指针实现用了Bitmap的偏移(旋转)操作。

     Matrix matrix = new Matrix();matrix.postRotate(degrees);Bitmap newBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),  matrix, true);

完成项目代码连接

Andoird开发--指南针(基于手机传感器)相关推荐

  1. 基于IndRNN的手机传感器动作识别

    近日,来自山东大学和电子科技大学的研究者提出了基于 IndRNN 模型利用手机传感器实现动作识别的网络,该模型解决了现有 RNN 模型的梯度消失和梯度爆炸问题,一定程度上实现了动作识别的用户独立性,同 ...

  2. 智能判断图片中是否存在某物体_基于WT901传感器及NB-IOT无线技术开发的一款物体倾倒监测设备...

    基于维特智能WT901传感器 及NB-IOT无线技术 开发的一款物体倾倒监测设备 一. 设备功能描述 该设备主要用于物体倾倒时的状态检测,通过维特智能[WT901]定时检测角度状态来判断物体是否倾倒: ...

  3. 使用 Qt for Android 获取并利用手机传感器数据(上篇)开发环境省心搭建

    现代手机拥有许多传感器,包括地磁.姿态.GPS.光照.温度.气压.摄像.声音.电磁等,完全就是一个高度集成的科学仪器.不夸张的说,一部手机加上一个外围的计算机和控制系统,做一个功能较强的自主移动机器人 ...

  4. Android 是Google开发的基于Linux平台的开源手机操作系统

    Android 是Google开发的基于Linux平台的开源手机操作系统(在华注册商标名为"安致").它摩托罗拉的首款Android手机CLIQ包括操作系统.用户界面和应用程序 - ...

  5. 《大富翁手机游戏开发实战--基于Cocos2d-x 3.2引擎》现已登陆各大网络销售平台发售

    <大富翁手机游戏开发实战--基于Cocos2d-x 3.2引擎>现已登陆各大网络销售平台发售! 部分网售地址: 当当:http://product.dangdang.com/2378178 ...

  6. 基于惯性传感器的轨迹记录系统

    概述 惯性导航代表了一种独特的导航方法,其中不依赖于外部信息源.与其他位置固定导航技术相反,惯性导航相对于移动平台的初始导航状态在相对意义上执行导航.因此,惯性导航系统不容易出现干扰或欺骗.惯性导航系 ...

  7. 计算机系统内网络平面图,基于手机的室内数字平面图构建方法-计算机工程.PDF...

    基于手机的室内数字平面图构建方法-计算机工程 第 卷 第 期 计 算 机 工 程 年 月 开发研究与工程应用 文章编号 文献标志码 中图分类号 基于手机的室内数字平面图构建方法 赵鹏飙 刘歌 罗磊 周 ...

  8. 利用计算机软件温度补偿,基于自主传感器信号调理芯片温度补偿的软件设计

    0 引言 针对压阻式压力传感器在应用中易发生温度漂移的问题,开发了一种智能压阻式传感器温度补偿系统.该方法利用现代信号调理技术,以信号调理芯片为核心,通过插值法对采集的温度补偿参数进行拟合,从而实现了 ...

  9. PaaS的发展将释放物联网开发效率 ——基于云架构的物联网云平台解决方案

    PaaS的发展将释放物联网开发效率 --基于云架构的物联网云平台解决方案 2018年7月6日.7日,为期两天的 ArchSummit 全球架构师峰会在深圳·华侨城洲际酒店拉开帷幕.在7月6日解决方案专 ...

  10. 【手机开发岗位职责|手机开发是做什么的】-看准网

    背景资料 3G时代的到来,使得手机应用日渐热门,由于手机携带方便,并且是生活必带随身用品,而且信号覆盖广,操作便捷,使得人们对其给予了越来越高的期望.大家期待各种常见的或是重要的信息化系统.互联网应用 ...

最新文章

  1. 系统分析与设计 实验一用例模型
  2. 《强化学习周刊》第29期:Atari 深度强化学习的研究综述、金融强化学习的最新进展...
  3. 46 岁美国华裔“鞋王”意外去世,25 岁创业成亿万富翁
  4. mysql.server 文件是什么_mysql的启动脚本mysql.server及示例配置文件
  5. 安卓开发小知识 - 3
  6. “电商+金融”融合发展 开辟金融创新新路径
  7. WebService技术
  8. 1.5 对象类型转换:向上转型和向下转型
  9. python模拟http请求
  10. Android 系统(16)---应用启动过程
  11. Json-lib, 实现Java对象与JSON数据格式的互转
  12. 移动组件到指定坐标_《我的世界》传送石碑组件 史蒂夫表示跑路的日子终于结束了...
  13. 金融大规模毁灭性武器--高频统计套利
  14. C语言控制台窗口图形界面编程(八):鼠标事件
  15. 简单、快捷、低成本的超写实虚拟人平台来了……
  16. 卸载HP LaserJet 激光打印机的驱动程序--Win7环境
  17. 《Redis系列第五篇、hset与hget的使用|CSDN创作打卡》
  18. 数澜、宜信、贝壳三种数据中台建设模式探讨 | 数澜科技
  19. Android应用模拟返回键、home键
  20. Jinja2安装与基本API用法

热门文章

  1. gogo/protobuf proto.GoGoProtoPackageIsVersion2、proto3 版本 不一致
  2. node.js 刷csdn博客访问量
  3. flashfxp怎么用,flashfxp怎么用
  4. few-shot vid2vid部署安装及测试
  5. 【IT之路】连接MySQL遇到ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor:yes)问题
  6. [转载]Geronimo 叛逆者,第 8 部分: 未来的 Apache Geronimo
  7. 阅兵方阵 蓝桥杯 第九届JavaA
  8. jQuery基础之正则表达式及表单验证
  9. 注册Github账号
  10. css骨架图,【CSS】骨架屏 Skeleton 效果